2011-06-18 19 views
0

我試圖創建一個的NSMutableDictionary已經鑰匙由UIViewController的代表,就像這樣:設置委託類作爲主要的的NSMutableDictionary

-(void) registerAsLocationManagerDelegate:(id<RTALocationManagerDelegate>)lmDelegate forPeriodicUpdates:(NSTimeInterval)seconds 
{ 
    NSTimer* periodicTimer = [NSTimer scheduledTimerWithTimeInterval:seconds 
                   target:self 
                  selector:@selector(runPeriodicUpdates:) 
                  userInfo:nil 
                  repeats:YES]; 
    [periodicUpdateDelegates setObject:periodicTimer forKey:lmDelegate]; 
} 

然而,我的代碼崩潰,因爲這個錯誤:

*終止應用程序由於未捕獲的異常 'NSInvalidArgumentException',原因: ' - [RTALocationsListViewController copyWithZone:]:無法識別的選擇發送到實例0x1a9750'

的喲方式呢?我是否通過嘗試這樣做了完全錯誤的事情?我應該採取不同的方式嗎?謝謝你的幫助!

+0

一般來說,只要可能,您應該對關鍵對象使用「標準」類。如果你想使用你的自定義類,他們需要符合'NSCopying'協議(實現'-copyWithZone:'),你需要確保'-isEqual:'中相同的兩個對象也返回相同的值爲'-hash',並且您需要確保在對象位於字典中時,即使對象內部狀態發生更改,「-hash」也不會更改。 – 2011-06-18 11:06:10

回答

-1

NSDictionary只要符合NSCopying協議,密鑰可以是任何對象。

您得到的錯誤是因爲它copyWithZone是此協議的一部分,它可能不會由您的委託對象實現。 - 所以它不能成爲關鍵。

您的選擇是獲取您的類的字符串表示形式並將其用作關鍵字 - 但如果您有多個具有相同類的委託人(因爲那麼這些關鍵字不會是唯一的),這可能不起作用。或者,在委託類中實現NSCopying協議。

+1

-1。複製委託沒有多大意義。使用類名也沒什麼意義,並且使用委託的描述(應該有點獨特,因爲它包含了類的地址)是可疑的。最簡單可靠的方法是使用'[NSValue valueWithNonretainedObject:lmDelegate]'作爲關鍵。 –

0

當NSDictionary複製密鑰時,CFDictionary函數不會。改用CFDictionary(或利用「免費橋接」)。

+0

「CFDictionary函數不會」這並非完全正確。 CFDictionary允許你指定語義。所以你*可以*複製密鑰(例如'kCFCopyStringDictionaryKeyCallBacks'),或者你可以保留它們,或者根本不保留它們。它很靈活。 – user102008

+0

@ user102008:最後我檢查了''[[NSMutableDictionary setValue:forKey:]'做了一個顯式拷貝,而'CFDictionarySetValue()'沒有。這可能意味着如果你創建一個密鑰拷貝'CFDictionary'並免費橋接到'NSMutableDictionary',密鑰最終會被複制兩次。 –