我真的必须覆盖哈希只因为我重写isEqual:为我的子类?

时间:2011-03-03 09:57:27

标签: iphone ios hash

Apple的文档说如果我覆盖isEqual:,那么我必须覆盖hash以确保两个被认为相等的对象的哈希值相同isEqual:

然后我读了关于哈希的文档,下面是它的一部分:

  

因此,散列方法必须不依赖于任何对象的内部状态信息,或者必须确保在对象位于集合中时对象的内部状态信息不会发生变化。

我的自定义类MyClass有很少的成员是int和bool,NSArray包含MyClass的数量,如果所有成员都相等,我希望两个MyClass实例相等。

我对如何覆盖isEqual:但对于hash没有任何问题。 根据我的理解,hash应该通过使用位操作(如XOR或旋转移位)组合成员的哈希值来计算哈希值。

问题是如何以符合上述Apple要求的方式实施hash。 Docs说哈希值不应该依赖于内部状态(即成员),但我发现我必须使用它们来计算值。

甚至我真的需要实现它吗?因为我确定不会将此类用作NSDictionary的键,这是我知道使用hash的唯一方法。是否有其他地方使用hash我应该关心它?

1 个答案:

答案 0 :(得分:4)

有两个选项 - 要么不依赖于内部状态,要么确保在对象位于集合中时内部状态不会发生变化。

第二个选项允许您依赖内部状态来生成散列,但是当您在对象集合中时,您的对象必须是不可变的,因此更改它不会更改其散列。

Cocoa中的集合依赖于对象的散列来执行containsObject:等方法。

如果您的对象实现了依赖于其内部状态的哈希,将其插入到集合中然后更改,则其哈希将更改,并且该集合将失去对象的跟踪。