2011-01-11 28 views
0

這個問題讓我有點困惑。 在「.h」文件中。關於保留和複製的問題目標c

@property (nonatomic,retain) NSMutableString *str1; 
@property (nonatomic,copy) NSMutableString *str2; 

在「.m」文件中。

NSMutableString *testRetain = [[NSMutableString alloc] initWithString:@"prefix"]; 
NSLog(@"retain count is %d",[testRetain retainCount]); 
NSLog(@"mem add is %p",testRetain); 

str1 = testRetain; 
NSLog(@"retain count is %d",[testRetain retainCount]); 
NSLog(@"mem add is %p",testRetain); 

str2 = testRetain; 
NSLog(@"retain count is %d",[str2 retainCount]); 
NSLog(@"mem add is %p",str2); 

所有的retainCount和內存地址都是一樣的。 據我所知,@property(nonatomic,retain)將添加被指向的對象的retainCount。因此,代碼的第二部分應輸出相同的內存地址,並從第​​一部分代碼輸出不同的containsCount。 和@property(nonatomic,copy)會將對象複製到一個新的區域。所以第三部分代碼應該從代碼的第一部分輸出不同的內存地址。 爲什麼我得到了這個結果。 非常感謝。

+0

您得到了什麼結果? –

+3

'str1 = testRetain'正在將伊娃直接設置爲相同的內存地址。要使用訪問器,你必須使用'self.str1 = testRetain; self.str2 = testRetain' – mackross

+0

馬克羅斯是正確的。 –

回答

4

兩點。首先,也是最重要的:不要使用retainCount作爲調試工具。有很多原因可能導致您無法獲得您期望的價值。它在文檔中說的很多。

但在這種情況下 - 第二點 - 它不工作的原因是您直接訪問變量而不是使用訪問器。

相反的:

str = testRetain; 

嘗試:

self.str = testRetain; 
3

通過使用「str1」而不是「self.str1」,你不會通過你的(大概合成的)屬性訪問器方法,所以他們做的內存管理不會發生。

作爲附加說明,您應該對使用-retainCount方法非常謹慎。 Cocoa Touch通常會使用保留計數(內部保留,釋放和自動釋放,爲常量對象存儲「特殊」保留計數等)來做非常奇怪的事情,這使得難以不可能有效使用。我建議考慮將保留計數(通過-copy,-alloc,-retain,+ new或-mutableCopy)遞增爲「聲明對象的所有權」並遞減它(通過 - 釋放或 - 釋放)爲「放棄對象的所有權」。所以只要你總是擁有你正在使用的每個對象,並在你完成它們時放棄它們,你應該避免泄漏和崩潰。

3

你應該使用什麼樣的其實是這樣的代碼:

self.str1 = ...; 

只有這樣的setter方法將被調用。

通過編碼是這樣的:

str1 = ...; 

你實際上是直接訪問實例變量不調用setter方法,因此沒有保留/複製發生。

1

str1 = testRetain;直接設置伊娃到相同的內存地址。 要使用訪問器,您必須使用

self.str1 = testRetain; 
self.str2 = testRetain;