NSSet是否使用哈希来定义唯一性?

时间:2011-03-02 01:15:11

标签: iphone objective-c cocoa-touch nsset

我一直在假设NSSet使用hash来查找潜在的匹配,然后在每个上面调用isEqual来检查真正的冲突,但我意识到我找不到任何证据支持这个

我提出它的原因是NSSet中存在“member:”方法。为什么成员的文档:尽量指定isEqual:用于在NSSet中没有别的时候找到你的对象? containsObject:只使用哈希值吗?

任何人都可以确认这种行为吗?理想情况下,参考文档呢?

2 个答案:

答案 0 :(得分:18)

我建议阅读Collections Programming Topics,特别是“集合:无序的对象集合”部分。在那里,您将找到以下信息:

  

此性能信息假定   适当的哈希实现   为对象定义的方法。有了   糟糕的哈希函数,访问和编辑   采取线性时间。

  

集合中的对象必须响应   NSObject协议方法哈希和   isEqual :(有关更多信息,请参阅NSObject   信息)。如果可变对象是   存储在集合中,或者是散列   对象的方法不应该依赖   关于可变的内部状态   对象或可变对象   不应该在他们进入时进行修改   集合。例如,一个可变的   字典可以放在一个集合中,但是   你不能改变它   那里。 (注意,这可能很困难   知道一个给定的对象   在一个集合中。)

所以,是的,hashisEqual按照您的假设使用。

答案 1 :(得分:13)

我想介入并提供有关NSSet使用hashisEqual:的更多信息,因为我最近遇到了一些奇怪的错误,并发现它们是由于我忽略{{1} }。

当您在一个集合中存储自定义对象时,NSSet使用您的hash方法返回的值来对不同容器中的对象进行分组,在这些容器中使用各自的hash方法将它们相互比较。所以基本上,在插入,构建,测试成员资格等时,将始终在对象上调用isEqual:,如果此对象落入存在其他对象的bin中,则hash 1}}方法将用于区别于它们。

这就是为什么isEqual必须总是对于被认为相等的对象是相同的,并且尽可能地产生将均匀分布对象的值。后一种属性可确保垃圾箱尽可能小,从而最大限度地减少对hash的调用。