苹果是如何实现NSSet的?

5

Apple目前的文档并没有记录NSSet中“identity”的概念。

我发现了一些看起来来自于Apple代码的bug。例如,“[NSMutableSet minusSet]”从未按照文档工作 - 但我非常确信这是由于“身份”的原因。

例如:http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSSet_Class/Reference/Reference.html#//apple_ref/occ/cl/NSSet

containsObject:

返回一个布尔值,指示给定对象是否存在于集合中。

如果anObject存在于集合中,则为YES,否则为NO。

那是什么意思?

我尝试过:

  1. 在集合中的所有类上实现“isEqual:”
  2. 检查所有类都是相同的类(无子类/父类混淆)
  3. 在集合中的所有类上实现NSCopying(没有效果)
2个回答

9
在Cocoa中,对象的相等性是通过使用isEqual:hash:来实现的。

https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html

isEqual:的注释中可以看出:

如果两个对象相等,则它们必须具有相同的哈希值。如果您在子类中定义了isEqual:并打算将该子类的实例放入集合中,则此最后一点尤为重要。确保您还在子类中定义了哈希。

您的子类将需要实现这两个方法,以便它们返回相同的内容。一旦这样做,那么它们就可以在Cocoa集合中正确使用。

您的NSSet相等性无法正常工作的原因是,集合使用哈希(存储为哈希表),因此如果您只实现了isEqual:,则它们的哈希可能(很大程度上)不同。


6

NSSet是传统意义上的哈希集合,因此您需要实现hash方法来确保对象被识别为相等的。默认情况下,hash仅返回强制转换为无符号整数的对象指针,这对于每个对象是唯一的,因此即使在isEqual:返回true的对象中,也不会被识别为相同的对象。如果您对NSSet的工作原理感兴趣,可以查看CFSet源代码,它是NSSet的桥接Core Foundation计数器部分。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接