Objective c NSObject isEqual:和哈希默认函数是什么?
我有一个数据库模型类,它是一个Objective c NSObject isEqual:和哈希默认函数是什么?,objective-c,nsarray,nsobject,Objective C,Nsarray,Nsobject,我有一个数据库模型类,它是一个NSObject。我在NSMutableArray中有一组这样的对象。我使用indexOfObject:查找匹配项。问题是模型对象的内存地址更改。因此,我重写了hash方法以返回模型的行ID。但是这并不能修复它。我还必须重写isEqual:方法来比较hash方法的值 默认情况下,isEqual:方法使用什么来确定相等性? 我假设它使用内存地址。阅读文档后,我认为它使用了散列方法中的值。显然,情况并非如此,因为我试图覆盖该值并没有解决我的初始问题。我假设NSObjec
NSObject
。我在NSMutableArray
中有一组这样的对象。我使用indexOfObject:
查找匹配项。问题是模型对象的内存地址更改。因此,我重写了hash
方法以返回模型的行ID。但是这并不能修复它。我还必须重写isEqual:
方法来比较hash
方法的值
默认情况下,isEqual:
方法使用什么来确定相等性?
我假设它使用内存地址。阅读文档后,我认为它使用了
散列方法中的值。显然,情况并非如此,因为我试图覆盖该值并没有解决我的初始问题。我假设NSObject
等质量使用=
运算符,而哈希
使用内存地址
isEquals
方法不应使用hash
作为对相等性的绝对测试。如果搜索足够多的对象(只需创建2^32个以上的不同对象,其中至少有两个对象具有相同的哈希
)
换句话说,hash
需要以下规范:如果两个对象相等,那么它们的hash
需要相等;但是,如果两个对象的
散列
值相等,则它们不一定相等
作为提示,您应该始终同时覆盖
isEquals
和hashCode
。正如您正确猜测的那样,NSObject
的默认isEqual:
行为是比较对象的内存地址。奇怪的是,这一点目前没有记录在文档中,但它记录在文档中,其中指出:
isEqual:
的默认NSObject
实现只是检查指针是否相等
当然,如您所知,
NSObject
的子类可以覆盖isEqual:
以实现不同的行为。例如,NSString
的isEqual:
方法,当传递另一个NSString
时,将首先检查地址,然后检查字符串之间的精确文本匹配。关于isEqual:
的默认实现的答案是全面的。因此,我只是添加了关于散列的默认实现的注释。这是:
-(unsigned)hash {return (unsigned)self;}
也就是说,它与isEqual:
中使用的指针值相同。以下是您可以查看此信息的方式:
NSObject *obj = [[NSObject alloc] init];
NSLog(@"obj: %@",obj);
NSLog(@"hash: %x",obj.hash);
结果会是这样的:
obj: <NSObject: 0x16d44010>
hash: 16d44010
obj:
哈希:16d44010
致以最良好的祝愿
顺便说一句,在iOS 8中,哈希成为了一种属性而不是一种方法,但它确实存在。这里有一些推测性的答案。有人能提供默认isEquals使用address>的实际文档吗?我不是说没有,只是想从马口中听到。@DougW我和你分享了这方面的感受,所以我找到了一份官方参考资料,并将其编辑为可接受的答案。你正在阅读NSObject协议的文档,不是NSObject类。协议定义了方法应该做什么,而类无法定义它实际做什么。重写equals和hash总是最安全的方法,以使它们按照您希望的方式工作。@TerryWilcox不,这是记录在案的,正如在接受的答案中所引用的那样。它只是没有记录在类引用中,这是您所期望的。绝对没有必要重写isEqual:
来执行与=
的显式指针比较,只是为了安全地传递indexOfObject:
某个任意NSObject
子类的实例-您可以相信NSObject
的isEqual:
将进行指针比较。@TerryWilcox我同意关于这一点的文档非常糟糕,但我认为建议您始终覆盖isEqual:
,而不信任NSObject
的实现太过分了。显然,如果指针相等(这是NSObject
的isEqual:
实现检查的内容)不是您真正想要的,那么您应该重写它。这方面的参考很好。。。。所以我加了一个。奇怪的是,NSObject
类引用甚至没有isEqual:
的条目,更不用说在任何地方描述它的行为了,这似乎是一个明显的遗漏。不过,我在文档“概念”部分的某个模糊页面上找到了一个官方参考。苹果文档中充斥着协议方法未在类文档中记录的情况。(更不用说超类方法了。)你经常需要在很多岩石下面寻找一个给定方法的文档。(我真希望苹果的文档更像Java,所有继承的方法至少都有一个类的描述。)