2011-10-17 22 views
5

假設「someData」是包含一些字節數據的NSMutableData。瞭解NSString的initWithBytes

如果我寫了以下內容:

NSString *someString = [NSString string]; 
[someString initWithBytes:[someData mutableBytes] length:[someData length] encoding:NSUTF8StringEncoding]; 

第二行給了我一個「無法識別的選擇發送到實例」錯誤

但如果我寫:

NSString *someString=[[NSString alloc] initWithBytes:[someData mutableBytes] length:[someData length] encoding:NSUTF8StringEncoding]; 

那麼它的工作原理。前一種方式不奏效是否有原因?可以不用「alloc」來完成,(事先創建someString?)

謝謝。

+1

您應該閱讀「[Objective-C編程語言](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Introduction/introObjectiveC.html)」的基礎知識。 – sidyll

+0

你的問題應該是'alloc'&'init'而不是'NSString'方法。 – Richard

回答

4

的原因是,[NSString string]返回的對象並沒有選擇迴應-initWithBytes:length:encoding:。這是因爲NSString的是不可變的 - 一旦創建它們就不能更改。方法-string利用了這一點,只是給你提供了一個空的常量字符串(在編譯時創建)的引用。

不僅如此,而且NSString是一個類集羣。這意味着,當你要求一個NSString時,你可能實際上得到了它的一個子類的一個實例。我的猜測是,你得到一個覆蓋了-initWithBytes:length:encoding:的子類拋出異常,因爲將init方法發送到在編譯時創建的常量字符串是沒有意義的。

在第二種情況下,您在運行時創建一個全新的NSString,然後向它發送一條init消息。這很好。請注意,因爲它是一個類集羣,所以init方法返回的字符串可能與-alloc創建的字符串不同。

+0

我想我明白了。前一種情況在編譯時創建一個NSString。一旦創建,就不能重新初始化。後一種情況在運行時創建一個字符串對象並在同一行上初始化它。但是,在第一種情況下用[someString init]替換第二行不會導致錯誤。也許是它的類集羣問題。 – Dave

3

第一種方法創建一個空的自動釋放字符串,該字符串已經被初始化,然後嘗試第二次初始化該字符串。第二種方式分配內存,然後適當地初始化它。請注意,第二種方法不會自動釋放已創建的字符串,因此調用作用域仍然負責。如果你願意,你可以包裝在的NSString的類別的便捷方法的第二種方式來獲得類似於第一更多的東西:

@interface NSString (stringWithBytes) 

+ (NSString*)stringWithBytes:(const void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding; 

@end 

@implementation NSString (stringWithBytes) 

+ (NSString*)stringWithBytes:(const void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding { 
    NSString * aString = [[NSString alloc] initWithBytes:bytes length:length encoding:encoding]; 
    return [aString autorelease]; 
} 

@end 
+1

它們不應該是類方法嗎? – jrturton

+0

啊,很好。我會編輯匹配。直接鍵入代碼而不是從Xcode粘貼總是會導致某些內容被遺漏。 – RPeck

+1

我在_phone_上輸入了很多答案。這是一個奇蹟,我有任何代表。 – jrturton