NSMutableDictionary的NSInvalidArgumentException/copyWithZone异常

Rob*_*son 6 iphone

我有一个类,我正在封装ABRecordID,当它被用作添加到NSMutableDictionary的键时,我得到运行时异常:

"NSInvalidArgumentException:*** - [MyRecordId copyWithZone:]:无法识别的选择器发送到实例"

MyRecordId声明为:

@interface MyRecordId : NSObject {
    ABRecordID abRecordId;
}

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

@end
Run Code Online (Sandbox Code Playgroud)

添加到词典:

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
MyRecordId *recordId = [[MyRecordId alloc] initWithId:anABRecordId];
[dict setObject:@"hello" forKey:recordId];
Run Code Online (Sandbox Code Playgroud)

最后一行导致异常..我知道你不能将非对象类型存储为字典的键,但我认为将它包装在NSObject派生类中会使它没问题.

我不应该将ABRecordID存储在其他对象中吗?我应该做别的吗?

Mar*_*pic 7

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

[dict setObject:@"hello" forKey:[NSNumber numberWithInt:recordId]];
Run Code Online (Sandbox Code Playgroud)

要再次获取recordId,请执行以下操作:

recordId = [[dict objectForKey:@"hello"] intValue];
Run Code Online (Sandbox Code Playgroud)


Chu*_*uck 6

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


die*_*ikh 6

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

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

  • 我亲自去'NSValue valueWithNonretainedObject',应该适合你.请记住,它当然不会为你保留你的物品...... (2认同)