18

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

我提出它的原因是 NSSet 中存在“member:”方法。为什么 member: 的文档特意指定 isEqual: 用于在 NSSet 中没有其他内容时用于查找您的对象?containsObject: 是否只使用哈希或其他什么?

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

4

2 回答 2

19

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

此性能信息假定为对象定义的散列方法有足够的实现。如果散列函数不好,访问和编辑需要线性时间。

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

所以,是的,hashisEqual就像你假设的那样使用。

于 2011-03-02T01:43:38.500 回答
14

我想介入并提供有关 NSSet 使用hashand的更多信息isEqual:,因为我最近遇到了奇怪的错误,发现它们是由于我忽略了hash.

当您将自定义对象存储在一组中时,NSSet 使用您的hash方法返回的值将对象分组到不同的 bin 中,在这些 bin 中使用各自的isEqual:方法将它们相互比较。所以基本上,hash在插入、构建、测试成员资格等时总是会在您的对象上调用,如果该对象落入有其他对象的 bin 中,将使用其isEqual方法将其与它们区分开来。

这就是为什么对于被认为相等的对象hash必须始终相同,并且尽可能产生将均匀分布对象的值。后一个属性确保 bin 尽可能小,从而最大限度地减少对isEqual:.

于 2013-07-12T04:49:01.743 回答