使用NSMutableDictionary(Objective-C)的对象键

使用NSMutableDictionary(Objective-C)的对象键,objective-c,nsdictionary,key-value,Objective C,Nsdictionary,Key Value,我想存储一组键值对,键值是从NSObject继承的我自己的对象(ObjectA),值是int。 我正在尝试使用NSMUTABLE字典。我知道您只能在字典中存储对象类型,因此我有以下几点: id value = [NSNumber numberWithInt:my_number]; [[self dictionary] setObject:value forKey:myObjectA]; 这给了我一个错误,说 -[ObjectA copyWithZone:]:发送到实例的选择器无法识别 很好,

我想存储一组键值对,键值是从NSObject继承的我自己的对象(ObjectA),值是int。
我正在尝试使用NSMUTABLE字典。我知道您只能在字典中存储对象类型,因此我有以下几点:

id value = [NSNumber numberWithInt:my_number];

[[self dictionary] setObject:value forKey:myObjectA];
这给了我一个错误,说

-[ObjectA copyWithZone:]:发送到实例的选择器无法识别

很好,我知道对象密钥需要实现NSCopying协议。然而,我后来读到,您可以通过使用NSValue包装对象来实现这一点

有人能解释一下我将如何包装我的对象,以及如何通过键找到值吗?我是否仍然能够使用
字典对象forkey:myObjectA
,或者在搜索时也必须使用NSValue对象包装myObjectA?或者我应该在自定义类上实现NSCopying,还是使用字符串键


我正在寻找使用字典的最简单和最简单的方法,如果必须的话,我将实现一个字符串键并使用setValue:forKey:取而代之,但如果可以的话,我宁愿使用object键。

您可以将
id
转换为NSValue,并使用:

NSValue* value = [NSValue valueWithNonretainedObject:object];
...
id object_ = [value nonretainedObjectValue];
但是您需要在字典之外管理所有权。这将是一场混乱。最好采用非复制方式


还有第四个选项:使用CFDictionary,它只允许对象被CFRetain/CFReleased,而不允许复制

CFMutableDictionaryRef dict = CFDictionaryCreateMutable(
     kCFAllocatorDefault, 0,
     &kCFTypeDictionaryKeyCallBacks,
     &kCFTypeDictionaryValueCallBacks
);

...

CFDictionarySetValue(dict, myObjectA, value);
...

CFRelease(dict);

如果您正在为Mac或iOS 6及以上版本编程,请尝试NSMapTable

NSMapTable* dict = [[NSMapTable mapTableWithStrongToStrongObjects] retain];
...
[dict setObject:@"?" forKey:foo];
...
[dict release];

您不需要使用NSValue包装对象。你所拥有的会有用的,除非你缺了一块。对于myObjectA类,您需要采用NSCopying协议(请参阅以了解要添加的内容)。一旦添加了这些代码,您在上面发布的代码就会正常工作


您可能想考虑在字符串中为自己的对象使用字符串。如果要使用键值编码来访问该键,则该键必须是字符串。因此,如果您可以在使用字典的任何地方利用键值编码,那么使用字符串将使工作更轻松。

字典键总是被复制的。因此,您只需要为类实现协议,这就是
copyWithZone:
方法

此外,您应该为类实现
isEqual:
方法


编辑:如何实现您的
copyWithZone:
取决于许多因素(主要因素:深度拷贝与浅层拷贝)。请参阅《苹果指南》和。

在iOS 6中,您可以使用NSMapTable(),这允许您为键和对象选择弱/强属性。

您可以扩展您的答案以包括我将在我自己的类中的copyWithZone实现中放置的内容吗?如果您实现了
-isEqual:
,则需要实现
-hash
,如果两个对象由
-isEqual:
确定相等,则它们必须具有相同的哈希值。感谢您提供有关使用NSValue的提示。我没有意识到这种实用性,这正是我所需要的。这似乎是一个更恰当的解决问题的办法。