2010-09-01 117 views
0

請仔細閱讀下面的代碼,並解釋爲什麼它在最後一行崩潰?NSMutableDictionary內存管理

NSMutableDictionary *dic1 = [[NSMutableDictionary alloc] initWithCapacity:10]; 
NSString *val = [[NSString alloc] initWithFormat:@"Deepak"]; 
NSString *key = [[NSString alloc] initWithFormat:@"First Name"];  

int a = [val retainCount]; 
a = [key retainCount]; 

[dic1 setObject:val forKey:key]; 
a = [val retainCount]; 
a = [key retainCount]; 

//self.mainDic = [dic1 copy]; 
self.mainDic = [dic1 mutableCopy];//mainDic is like @property(copy) NSMutableDictionary * 
[self.mainDic setObject:@"Hi" forKey:@"Good"];//Problem 

謝謝。

回答

2

copy屬性不適合可變類,因爲他們不尊重的可變性,並只發送copy消息的情況下 - 會發生什麼在倒數第二行基本上是:

// ... release previous mainDic, if any 
mainDic = [[dic1 mutableCopy] copy]; 

由於copy消息導致一個不可變的版本,NSDictionary,您可能在調試時遇到無法識別的選擇器-setObject:forKey:

如果你想使用copy屬性,你應該提供你自己的二傳手,並刪除該手冊mutableCopy - 見例如。蘋果文檔在copy semantics

1

我幾乎從來沒有使用過的屬性比其他改性劑(非原子,保留) 這爲我節省了很多的問題, 這一點,在dealloc方法set'em爲零

這是我會這樣做的方式

NSMutableDictionary *dic1 = [[NSMutableDictionary alloc] initWithCapacity:10]; 

NSString *val = [[NSString alloc] initWithFormat:@"Deepak"]; 
NSString *key = [[NSString alloc] initWithFormat:@"First Name"];  

[dic1 setObject:val forKey:key]; 

self.mainDic = dic1; //where mainDic is like @property (nonatomic, retain) NSMutableDictionary * 

[self.mainDic setObject:@"Hi" forKey:@"Good"]; 

//let's clean this mess up 
[val release]; 
[key release]; 
[dic1 release]; 
+0

現在如果有問題的對象來自課堂外部,並在以後從外部改變,從而破壞封裝?見例如[複製部分]的第一部分(http://developer.apple.com/mac/library/documentation/cocoa/conceptual/objectivec/Articles/ocProperties.html#//apple_ref/doc/uid/TP30001163-CH17- SW32)在文檔中。 – 2010-09-01 12:57:20

+0

我只是說我從來沒有使用副本,在這些情況下 - 維護一個可以在外面改變的對象,我仍然想保留過時的副本 - 我已經設法制作一個克隆方法,我來自C#所以我使用複製不舒服。 – 2010-09-01 13:47:08

+0

建議您不要在dealloc中使用屬性。而不是將屬性設置爲零,你應該釋放inst vars。 – JeremyP 2010-09-01 14:03:41

0

@Deepak!你的代碼本身運行良好。除了不引用dic1的內存泄露外,沒有靜態分析錯誤。

self.mainDic = [dic1 mutableCopy];效果很好。請再次運行您的代碼塊。 我創建了一個新項目,並將您的代碼和測試。沒有問題。

@Georg Fritzsche你的代碼崩潰了。

+0

什麼代碼?我只說*「用你的代碼就有這樣的事情發生」*。 – 2010-09-01 13:01:08

+0

@Georg Fritzsche當我在放入下面的代碼後運行@ Deepak的代碼時,發生崩潰。 mainDic = [[dic1 mutableCopy] copy]; – alones 2010-09-01 15:13:46

+0

**我沒有說要使用該代碼** ......這是一個「副本」屬性的效果的例子。讓我猜猜,你測試'mainDic'的'retain'或'assign'屬性?在這種情況下,你不會有OP的問題。 – 2010-09-01 15:19:44