我一直在假设 NSSet 使用 hash 来查找潜在的匹配项,然后在每个匹配项上调用 isEqual 来检查真正的冲突,但我意识到我找不到任何证据来支持这一点。
我提出它的原因是 NSSet 中存在“member:”方法。为什么 member: 的文档特意指定 isEqual: 用于在 NSSet 中没有其他内容时用于查找您的对象?containsObject: 是否只使用哈希或其他什么?
任何人都可以确认这种行为吗?理想情况下,有关它的参考文档?
我一直在假设 NSSet 使用 hash 来查找潜在的匹配项,然后在每个匹配项上调用 isEqual 来检查真正的冲突,但我意识到我找不到任何证据来支持这一点。
我提出它的原因是 NSSet 中存在“member:”方法。为什么 member: 的文档特意指定 isEqual: 用于在 NSSet 中没有其他内容时用于查找您的对象?containsObject: 是否只使用哈希或其他什么?
任何人都可以确认这种行为吗?理想情况下,有关它的参考文档?
我建议阅读集合编程主题,特别是“集合:对象的无序集合”部分。在那里,您将找到以下信息:
此性能信息假定为对象定义的散列方法有足够的实现。如果散列函数不好,访问和编辑需要线性时间。
和
集合中的对象必须响应 NSObject 协议方法 hash 和 isEqual:(有关更多信息,请参阅 NSObject)。如果可变对象存储在集合中,则对象的哈希方法不应该依赖于可变对象的内部状态,或者当可变对象在集合中时不应该修改它们。例如,一个可变字典可以放在一个集合中,但是当它在那里时你不能改变它。(请注意,很难知道给定对象是否在集合中)。
我想介入并提供有关 NSSet 使用hash
and的更多信息isEqual:
,因为我最近遇到了奇怪的错误,发现它们是由于我忽略了hash
.
当您将自定义对象存储在一组中时,NSSet 使用您的hash
方法返回的值将对象分组到不同的 bin 中,在这些 bin 中使用各自的isEqual:
方法将它们相互比较。所以基本上,hash
在插入、构建、测试成员资格等时总是会在您的对象上调用,如果该对象落入有其他对象的 bin 中,将使用其isEqual
方法将其与它们区分开来。
这就是为什么对于被认为相等的对象hash
必须始终相同,并且尽可能产生将均匀分布对象的值。后一个属性确保 bin 尽可能小,从而最大限度地减少对isEqual:
.