2010-11-11 38 views
1

任何一個可以告訴之間的區別:ALLOC一個字符串,並給予價值直接

NSString* myStr = @"Some value"; 

NSString* myStr = [[NSString alloc] initWithString:@""]; 

爲什麼我應該ALLOC一個字符串,即使我可以直接給一些價值..?

+0

我已經用Cocoa編程了大約8年,我從來沒有像這樣直接分配過一個NSString。我想不出有什麼理由要這樣做。 – JeremyP 2010-11-11 15:48:35

回答

2

從蘋果公司的String Programming Guide, 「Creating Strings

創建源代碼的字符串對象的最簡單方法是使用Objective-C的@ 「...」 結構:

NSString *temp = @"/tmp/scratch"; 

請注意,以這種方式創建字符串常量時,應避免使用除7位ASCII字符之外的任何內容。這樣的對象是在編譯時創建的,並存在於整個程序的執行過程中。編譯器使這些對象常量在每個模塊的基礎上都是唯一的,並且它們永遠不會被釋放,儘管您可以像其他對象一樣保留和釋放它們。

「編譯器使得這樣的對象常量獨特的[...]」建議,我認爲字符串文字interned每個模塊。據我所知,實習生和對象生存期內存管理是兩種方法的主要區別。

至於爲什麼一個可能使用後者,如果由於某種原因,你想myStr不是唯一的,實習的字符串,那麼你可以嘗試-initWithString:方法,雖然實習串仍將存在,使用-copy會更簡單(正如NR4TR指出的那樣),並且(正如Yuji在註釋中註釋的那樣),儘管Apple的文檔建議了什麼,但結果字符串可能與字符串字符串完全一樣。

+1

最後一段不正確。正如你可以自己檢查一樣,當前實現的'NSString','NSString * foo = [[NSString alloc] initWithString:@「boo」]'只是返回相同的'@「boo」'作爲優化。這是一個實現細節,你不應該依賴它;特別是,你應該仍然釋放'foo'。但它並不能保證'foo'與'@「boo」'不同。 – Yuji 2010-11-11 13:40:55

+0

Apple文檔再次觸發(輸出)。 '-initWithString:'(和'+ stringWithString')表示從源文件拷貝字符(儘管'-initWithString:'可能返回一個不是原始接收者的對象)。返回源不會複製任何字符。 – outis 2010-11-11 14:01:52

+0

文檔在精神上是正確的。只是如果您是從一個不能更改的常量字符串進行初始化,那麼該副本會被優化。 – JeremyP 2010-11-11 15:45:47

2

考慮要存儲被傳入AA串,完全相同的方式,因爲它是在傳遞時:

@implementation AddressCard; 

-(NSString *) name 
{ 
    return name; 
} 

-(void) setName: (NSString *) theName 
{ 
    [name release]; 
    name = [[NSString alloc] initWthString: theName]; 
} 

//rest of class implementation code snipped 
@end 

如果你只會用

-(void) setName: (NSString *) theName 
{ 
    [name release]; 
    name = [theName retain]; 
} 

然後NSMutableString是得到因爲名稱可以在以後更改,而不需要在AddressCard中明確設置name屬性。這通常不是人們想要的。

+1

我只是在第二個列表中使用'copy'而不是'retain'。並且沒有問題 – knuku 2010-11-11 11:12:47

+0

正如NR4TR所說,您應該使用複製。另外setName:有一個錯誤。如果'name == theName',則可能是由該版本釋放了名稱。 – JeremyP 2010-11-11 15:51:59

0

其所有的內存管理,因此,如果你寫

的NSString * myStr的= @ 「一些價值」;

它將分配字符串值與一些資源,並在腳本存儲器的末尾將被自動釋放,其中作爲第二殼體

的NSString * myStr的= [[的NSString的alloc] initWithString: @ 「」];

您分配了一些內存,在使用該變量後,您可以釋放變量的內存。因此你做自己的記憶管理。所以在第二種情況下,內存泄漏的可能性較小。第一種情況完全取決於垃圾收集,在這種語言的情況下,垃圾收集並不太可靠。

+0

我不相信這是正確的。在第二種情況下,內存泄漏的可能性更大,因爲如果程序員忘記釋放'myStr',那就是泄漏 - 而第一個永遠不會泄漏。 – makdad 2010-11-11 11:18:56

+1

在Cocoa的當前實現中,在任何情況下都不會有內存泄漏的機會。常量字符串永遠不會被釋放,並且initWithString:只是返回傳入的常量字符串。 – JeremyP 2010-11-11 15:53:58

+0

@phooze:是的,你正在編寫,因爲我忘了提及在xcode中釋放dealloc方法中的變量,或者在變量結束後使用它。因此,無論何時我們手動分配內存,它都會解除(釋放)變量的內存。抱歉沒有提到這一點,將來會照顧到這一點。 – 2010-11-12 04:50:56

相關問題