2009-06-25 33 views
6

我有我封裝ABRecordID與當它被用來作爲一個鍵添加到一個NSMutableDictionary,我得到的運行時異常的一類:NSInvalidArgumentException/copyWithZone異常與的NSMutableDictionary

「NSInvalidArgumentException: *** - [MyRecordId copyWithZone:]:無法識別的選擇發送到 實例」

MyRecordId聲明:

@interface MyRecordId : NSObject { 
    ABRecordID abRecordId; 
} 

-(id)initWithId:(ABRecordID)anABRecordId; 
@property (nonatomic) ABRecordID abRecordId; 

@end 

添加到字典:

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; 
MyRecordId *recordId = [[MyRecordId alloc] initWithId:anABRecordId]; 
[dict setObject:@"hello" forKey:recordId]; 

最後一行導致異常..我知道,你不能非對象類型存儲爲字典鍵,但我認爲它包裹起來NSObject的派生類會讓它好起來的。

我不應該存儲ABRecordID在其他對象?我應該做其他事嗎?

回答

7

使用的NSNumber存儲ABRecordID在一個OBJ-C等級:

[dict setObject:@"hello" forKey:[NSNumber numberWithInt:recordId]]; 

再次獲得的recordId,做到:

recordId = [[dict objectForKey:@"hello"] intValue]; 
6

NSDictionary鍵需要實現NSCopying協議。這就是爲什麼它告訴你你的對象不響應copyWithZone:

6

您用作關鍵值的對象的類應符合NSCopying協議。 基本上它應該實現copyWithZone:方法。

您應該使用NSValue類,而不是使用自己的類來包裝您的非對象變量,該類是專門爲此目的設計的,並且支持NSCopying協議。

+0

我不知道NSValue最適合這個用途。我將使用哪種初始化工具以「ABRecordID」構建它? – 2009-06-25 18:16:09

+2

我要與'NSValue valueWithNonretainedObject'個人,應該爲你工作。請記住,它不會爲你保留你的對象... – Chris 2011-09-28 00:29:52

0

您也可以將NSNumber用於此目的,因爲它從NSValue繼承。

0

Diederik在正確的道路上,但鑑於ABRecordID的類型,我建議使用NSNumberNSValue子類)。你可以使用-initWithInt:作爲ABRecordID這是一個int32_t

1

對於質疑我一樣的編碼,確保參數到setObject是正確的。我剛剛在這個錯誤上浪費了幾個小時,然後才注意到它們已經顛倒了!