Objective c 什么';使用NSObject';s哈希以创建NSMutableDictionary键?

Objective c 什么';使用NSObject';s哈希以创建NSMutableDictionary键?,objective-c,ios,Objective C,Ios,在一些地方,我需要对象到对象的映射,并使用NSMutableDictionary作为查找表。密钥是装箱的NSObject哈希,例如: [dict setObject:newObject forKey:[NSNumber numberWithUnsignedInt:[keyObject hash]]]; 其中,keyObject是自定义类的实例,该类按原样继承NSObject的-(NSUInteger)散列实现。我在别处保留了对keyObject的引用,我可以用它来获取newObject:

在一些地方,我需要对象到对象的映射,并使用NSMutableDictionary作为查找表。密钥是装箱的NSObject哈希,例如:

  [dict setObject:newObject forKey:[NSNumber numberWithUnsignedInt:[keyObject hash]]];
其中,keyObject是自定义类的实例,该类按原样继承NSObject的-(NSUInteger)散列实现。我在别处保留了对keyObject的引用,我可以用它来获取newObject:

[dict objectForKey:[NSNumber numberWithUnsignedInt:[keyObject hash]]]
到目前为止,这似乎是可行的,尽管相关的应用程序还很年轻

然而,马特·加拉赫(Matt Gallagher)写到了这种方法:

这稍微削弱了我的信心(因为这是针对iOS应用程序的,所以我不能使用他建议的NSMapTable)


有谁能指出以这种方式使用NSObject的散列有什么问题,对于iOS应用程序的简单对象映射来说,什么可能是更好的方法吗?

散列不一定是唯一的。

除了散列的非唯一性之外,如果您像这里所做的那样将它们塞进一个
unsigned int
中,实际上,您已经保证,即使是直接返回对象指针的
-hash
方法也不一定会产生唯一键

如果要执行此操作,则不要使用
NSNumber
,至少要将
NSValue
+valueWithPointer:
-pointerValue
方法一起使用


如果你真的想要一个代码> NSCORCHON/<代码>接口,并且由于某种原因不能使用<代码> NSMAPTABE>代码>,你可以使用核心基础来创建一个字典,它有原始对象指针作为它的键。如果您这样做,您甚至可以选择如何为您在字典中用作键的对象进行内存管理;例如,您可能想要保留键,您可能想要复制键,或者您可能决定只关心指针值本身。

NSObject的默认实现只是返回其内存位置,我认为。这应该足以在实例的生存期内指定实例相等性。如果直接使用对象的内存位置会怎么样?那么,如果其他人实现了不同的
散列
方法也没关系。是的,我可以这样做。但不管怎样,这正是MG在我链接的帖子中所嘲笑的。他清楚地看到,用这种方式将盒装内存地址用作密钥有问题(或者至少很有趣),我想知道为什么。还有,在obj c中伪装关联数组的更好方法是什么?也许他觉得拳击很尴尬?可能有更好的方法,但我认为使用内存地址没有任何问题。(我仍然会避免散列,因为我们无法控制被覆盖的行为。)@Cris:我同意乔恩的评论。读了这篇博文,我不认为Matt说不应该这样做,只是说这是一个棘手的解决问题的方法,现在通过
NSMapTable
的可用性解决了这个问题。直接使用地址,而不是依靠
散列
来避免被覆盖;一个对象的地址必须是唯一的,因此它应该作为一个键出色地工作。有趣的问题,顺便说一句,“鞋头”?在iOS上,
sizeof(NSUInteger)==sizeof(unsigned int)
@Josh Caswell:
在iOS上,sizeof(NSUInteger)==sizeof(unsigned int)
虽然目前可能是这样,但是
NSValue
valueWithPointer:
更清楚地说明意图吗?@drewk:我认为使用地址是正确的方法,而且
+[NSValue valueWithPointer::
是一个很好的方法。我只是想指出,alastair的答案似乎不正确地指向OS X。@alistair:NSObject的哈希返回一个NSUInteger(不需要shoehorn)。我之所以选择这条路线,是因为在iOS上我没有可用的NSMapTable。虽然我现在对CF不够熟悉,但CF路线在某种程度上可能很诱人。@drewk,@josh:NSValue和指针值看起来是个不错的选择。