2009-11-23 93 views
0

我知道v03示例創建了一個我擁有並最終必須釋放的對象。我想知道的是前兩個(v_01 & v02)之間是否有區別,還是它們基本相同?NSStrings之間的區別?

// Version_01 
userName = @"Teddy"; 

// Version_02 
userName = [NSString stringWithString:@"Gary"]; 

// Version_03 
userName = [[NSString alloc] initWithString:@"Caroline"]; 
... some code 
[userName release]; 

加里

+0

在這裏有很多類似的帖子,當然有人可以將其作爲副本關閉。 – 2009-11-23 18:58:44

回答

1

這些實例中的大部分差異是內存如何管理。如果您想更清楚地瞭解背景中發生的情況,您可能需要仔細閱讀Objective-C Memory Management Guide

// Version_01 
userName = @"Teddy"; 

這是一個字符串常量,沒有任何與其關聯的內存管理。用於保存該值的內存是代碼駐留的內存的一部分(基本上)。 retainrelease對該變量的調用將被忽略。

// Version_02 
userName = [NSString stringWithString:@"Gary"]; 

這是一個NSString對象的autoreleased實例。它的保留計數目前是一個,並將很快由autorelease池釋放,除非它被保留。

// Version_03 
userName = [[NSString alloc] initWithString:@"Caroline"]; 
[userName release]; 

這是一個NSString的託管實例。首次初始化時,其保留計數爲1。釋放後,保留計數降爲零,因此其內存將被釋放。在釋放後參考變量userName將導致EXE_BAD_ACCESS錯誤。

0

前兩個或基本相同

後者一個不是然而由於用戶名應該在該點無效字符串對象。

但是其更改爲

userName = [[[NSString alloc] initWithString:@"Caroline"] autorelease]; 

會使它實際上是相同的前兩個。

+1

爲什麼後者是「無效字符串對象」?它看起來完全有效 - 他分配一個NSString對象,將初始化的結果存儲在userName變量中,並根據需要釋放它。 – 2009-11-23 16:25:26

+0

,因爲他在下一行發佈它,在這一點上做任何事情都會導致崩潰。 – 2009-11-23 16:27:19

+0

我添加了發佈版本,以顯示在稍後的某個時刻,我意識到該對象需要發佈。在您陳述的時候,自動釋放可能會是一種更好的方式,至少在這種情況下您不太可能忘記添加釋放並避免泄漏。 – fuzzygoat 2009-11-23 16:45:19

0

版本01:是一個字符串常量.... 版本02:是一個通過複製常量創建的自動發佈的NSString。

+1

不安靜,如果你看一下調試器中的內存地址,你會看到'username = @「bobDole」'和'username = [NSString stringWithString:@「bobDole」]'實際上是指向同一個字符串對象的指針。 – 2009-11-23 16:25:32

4

他們都是相似的,但三者之間有一些細微的差異。

第一個是一個指向字符串常量的指針。字符串Teddy存儲在只讀存儲器中,並且userName是一個指向此字符串常量的指針。您不需要(也不能)保留或釋放此對象,因爲它「永久」存在(即在程序期間)。

第二個是自動發佈字符串對象,其內容爲Gary。返回給您時,它的發佈計數爲0.它可以根據需要保留和釋放。

第三個類似於第二個,但它是而不是 autoreleased,所以它最初返回給您時的保留計數爲1。就像第二個一樣,它可以根據需要保留和釋放。

+0

我真的想知道第一個不能被釋放或保留的事實,正如我在我的測試中看到的那樣:stringWithString和常量聲明導致指向相同內存地址的指針。 – 2009-11-23 16:28:35

+0

當然,這三者都是不可變的字符串,因此在這個意義上是「不變的」,但是不變的字符串實際上稍有不同,因爲它們永遠不會消失。 – Chuck 2009-11-23 16:29:47

+0

@Bryan:做一個不可變字符串''stringWithString:'可能會返回它的參數。你實際上可以釋放並保留一個常量字符串(否則你永遠不會傳遞一個setter方法),但它沒有任何作用。 – Chuck 2009-11-23 16:31:55

0

實際上,只要您在釋放後不嘗試使用Version_03字符串,就沒有區別。如果你想這樣做,你需要汽車而不是釋放它。