2012-10-19 25 views
6

我在我的項目中的一個問題,我的頭部聲明文件一個NSMutableDictionary屬性,像這樣:的iOS,的NSMutableDictionary

@property (copy, nonatomic) NSMutableDictionary *DataDict ; 

現在在實現文件中,我繼續和初始化本字典,因爲我要去使用它,就像這樣:

DataDict = [[NSMutableDictionary alloc]init]; 

現在我這樣做的時候,我嘗試的東西添加到這個字典一刻起,我會收到此錯誤信息:

- [__ NSDictionaryI的setObject:forKey:]:無法識別的選擇發送到實例0x885ae60 2012年10月19日16:51:56.040的測試[2297:C07] * 終止應用程序由於未捕獲的異常 'NSInvalidArgumentException' 的,原因是: 「 - [__ NSDictionaryI 的setObject:forKey:]:無法識別的選擇發送到實例0x885ae60」

過了一會兒,並通過我的項目一千倍運行,我決定取消註釋我的起始線,像這樣

//DataDict = [[NSMutableDictionary alloc]init]; 

並解決了這個問題。

我的問題是:爲什麼?

回答

15

問題出在你定義你的財產的方式。如果您將其更改爲:

@property (strong, nonatomic) NSMutableDictionary *DataDict ; 

,而不是copy一切都應該罰款。

發生這種情況是因爲您基本上說要通過生成的訪問器獲取對象的副本,而訪問器返回NSDictionary(不可變副本)。

你可以在objective-c properties here找到更多的信息。

正如旁註:objective-c ivars通常以小寫字母開頭(大寫字母用於類),所以dataDict應優於DataDict

+0

謝謝,我得讀一讀這些。 – Kalamantina

+0

這是否意味着我應該使引用強壯,然後alloc init?或者使其強大,並且不需要分配init? – Kalamantina

+0

通過使它變得「強壯」,你只是說你想與該對象保持強大的關係(擁有)(這基本上意味着當擁有者釋放時你希望它被釋放)。你仍然必須像往常一樣分配/初始化對象。 – Alladinian

2

這是因爲該屬性具有「copy」屬性,所以NSMutableDictionary實例alloc/init-ed使用「copy」方法「複製」ed,而「copy」方法不是創建NSMutableDictionary而是NSDictionary。 (「mutableCopy」將創建NSMutableDictionary)。

也許,您可以使用「保留」而不是「複製」作爲屬性。或者,只是沒有「複製」/「保留」而是使用ARC(自動引用計數)。