什么是NSObject isEqual:和哈希默认函数?

时间:2009-08-06 21:24:17

标签: objective-c nsarray nsobject

我有一个NSObject的数据库模型类。我在NSMutableArray中有一组这些对象。我使用indexOfObject:来查找匹配项。问题是模型对象的内存地址更改。所以我重写了hash方法以返回模型的行ID。然而,这并没有解决它。我还必须覆盖isEqual:方法来比较hash方法的值。

默认情况下isEqual:方法用于确定相等性的内容是什么?

我假设它使用内存地址。阅读isEqual:文档后,我认为它使用了hash方法中的值。显然,事实并非如此,因为我试图覆盖这个价值并没有解决我最初的问题。

3 个答案:

答案 0 :(得分:28)

正如您所猜测的那样,NSObject的默认isEqual:行为是比较对象的内存地址。奇怪的是,NSObject Class Reference目前尚未对此进行记录,但Introspection文档中对此进行了记录,其中指出:

  

NSObject的默认isEqual:实现只是检查指针是否相等。

当然,正如您无疑意识到的那样,NSObject的子类可以覆盖isEqual:以表现不同。例如,NSString的{​​{1}}方法,当传递到另一个isEqual:时,将首先检查地址,然后检查字符串之间的确切文字匹配。

答案 1 :(得分:9)

关于isEqual:默认实施的答案是全面的。所以我只是添加关于hash的默认实现的说明。这是:

-(unsigned)hash {return (unsigned)self;}

它就是isEqual:中使用的指针值。您可以在此处查看:

NSObject *obj = [[NSObject alloc] init];
NSLog(@"obj: %@",obj);
NSLog(@"hash: %x",obj.hash);

结果将是这样的:

obj: <NSObject: 0x16d44010>
hash: 16d44010

最诚挚的问候。

iOS 8中的BTW hash成为属性而非方法,但它就在那里。

答案 2 :(得分:4)

我认为NSObject isEquals使用==运算符,hash使用内存地址。

isEquals方法永远不应该使用hash作为相等的绝对测试。如果搜索足够多的对象(只创建超过2 ^ 32个不同的对象,并且其中至少两个具有相同的hashCode),则保证有两个具有相似hash的对象。 / p>

换句话说,hash需要以下规范:如果两个对象相等,那么它们的hash必须相等;但是,如果两个对象的hash值相等,则它们不一定相等。

作为提示,您始终应该一起覆盖isEqualshashCode