iOS的內存管理是否有從編譯器方面有關的NSString
NSString * str = @"123";
和
NSString * str = [[NSString alloc] initWithString:@"123"];
之間有什麼不同?
iOS的內存管理是否有從編譯器方面有關的NSString
NSString * str = @"123";
和
NSString * str = [[NSString alloc] initWithString:@"123"];
之間有什麼不同?
理論上是的;在實現細節中,可能不是。
在第一種情況下,編譯器創建一個常量字符串並將其指向變量str
。你不擁有字符串。
在第二種情況下,編譯器創建一個常量字符串(與以前一樣),但這次它被運行時用作初始化您擁有的另一個字符串的參數(因爲第二個字符串是使用alloc
創建的) 。
這就是你要知道需要的東西的結尾。
但是,有很多優化繼續。因爲NSStrings
是不可變的,所以你會發現initWithString:
實際上只是返回參數。通常情況下,它會在返回給你之前保留參數(因爲你期望擁有它),但是字面上的字符串有一個特殊的retainCount(我認爲是INT_MAX
),用來停止試圖釋放它們的運行時間。所以在實踐中,你的第二行代碼產生與第一行相同的結果。
順便說一句,這就是爲什麼它不正確的頂部說在第一種情況下字符串是autoreleased,因爲它不是。它只是一個具有特殊保留計數的常量字符串。
但是,您可以也應該安全地忽略實現細節並記住,在第一種情況下您不擁有該字符串,但在第二種情況下您確實擁有該字符串。
是的,在第一種情況下,你不擁有該字符串,你不負責釋放它。
在第二種情況下,您調用的是alloc
,因此您將成爲該對象的所有者,並且在完成後您必須調用release
,否則它將成爲內存泄漏。一般而言,如果您用來獲取對象的方法包含「新」,「分配」,「複製」或「mutableCopy」,那麼您就是對象的所有者,您有責任將其釋放。
是的。第一個是NSString的賦值,第二個是alloc
(這意味着你需要稍後以某種方式釋放它),並且initWithString:
方法被調用。
很多差異。最重要的是,您擁有第二個字符串,因此您必須負責釋放它(無論何時從init
方法中獲得對象時都是如此)。
另一個是前者創建一個字符串文字,如果你用相同的文字創建一個新的字符串,它們將指向同一個對象。如果你這樣做:
NSString * str1 = @"123";
NSString * str2 = [[NSString alloc] initWithString:@"123"];
NSString * str3 = @"123";
然後str1 == str2
是假的,但str1 == str3
是真實的。 (當然,字符串的內容是相同的,所以isEqual:
將返回true,並且,雖然這確實可以加快比較,但你可能不應該使用它,因爲它是一個實現細節,將來在理論上可能會發生變化)。
'str1 == str2'很可能是真的,但僅僅是因爲實現細節。 – bbum 2012-03-29 17:12:25
約內存(你的問題的標題)主重要的區別是: 當你這樣做:
NSString* myString = @"my text";
你分配NSConstantString類型的對象。
用的NSString的區別是: NSConstantString是靜態分配,而的NSString是動態分配。
差不多;實際上,'str'最終會引用靜態分配的字符串作爲實現細節。 'initWithString:'會看到'@「123」'是一個不可變的字符串,並且會簡單地返回它。 – bbum 2012-03-29 17:11:53
+1非常好的答案 – Saphrosit 2012-03-29 11:10:21