NSMutableDictionary的NSInvalidArgumentException / copyWithZone异常

时间:2009-06-25 17:45:22

标签: iphone

我有一个我正在封装ABRecordID的类,当它被用作添加到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存储在其他对象中吗?我应该做些什么吗?

6 个答案:

答案 0 :(得分:7)

使用NSNumber将ABRecordID存储在Obj-C类中:

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

再次获取recordId,执行:

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

答案 1 :(得分:6)

NSDictionary密钥需要实现NSCopying协议。这就是为什么它告诉你你的对象没有响应copyWithZone:

答案 2 :(得分:6)

用作键值的对象的类应符合NSCopying协议。 基本上它应该实现copyWithZone:方法。

不应使用自己的类来包装非对象变量,而应使用专为此目的而设计的NSValue类,并支持NSCopying协议。

答案 3 :(得分:1)

对于像我这样受到挑战的编码,请确保setObject的参数是正确的方法。我只是浪费了几个小时才发现这个错误,然后才注意到我把它们颠倒了!

答案 4 :(得分:0)

您也可以将NSNumber用于此目的,因为它继承自NSValue。

答案 5 :(得分:0)

Diederik位于正确的路径上,但考虑到ABRecordID的类型,我建议使用NSNumberNSValue子类)。您-initWithInt:使用的ABRecordIDint32_t