假设我有一个名为Person
的对象,该对象具有属性socialSecurityNumber
,并且当社会保障号码属性相等时,该类重写isEqual:
方法以返回true。假设我已经把一堆Person
的实例放到了一个NSDictionary
中。
如果我现在实例化一个newPerson
对象,它恰好与字典中已经存在的对象具有相同的社会保险号,并且我执行[myDictionary objectForKey:newPerson]
,它会使用isEqual:
并返回YES,还是会比较指针并返回NO?
我知道我可以写一个简单的测试来找出答案,但我想了解objectForKey:
是如何准确地在字典中找到匹配项的,以及这在整个Cocoa中的一致性(即NSArray
的indexofObject:
工作相同吗?)
NSDictionary
的工作原理类似于哈希表。因此,它使用-hash
和-isEqual:
在字典中查找与给定关键字相对应的对象。
因此,为了回答您对NSDictionary
的问题,这使用了isEqual:
,而不是指针比较。但是,除了isEqual:
之外,您还应该在Person
类上实现hash
,这样才能工作。
- 从NSDictionary类参考文档中:
字典中的键值对称为条目。每个条目由一个表示键的对象和另一个表示该键值的对象组成。在字典中,关键字是唯一的。也就是说,一个字典中没有两个键是相等的(由isEqual确定:)。
- 根据
isEqual:
方法文档:
如果两个对象相等,则它们必须具有相同的哈希值。如果您在子类中定义isEqual:并打算将该子类的实例放入集合中,那么最后一点尤为重要。确保您也在子类中定义了hash。
- 这种行为在Cocoa中的各种容器类中是一致的。例如,从
NSArray
的indexOfObject:
方法文档中:
从索引0开始,向数组的每个元素发送一条isEqual:消息,直到找到匹配项或到达数组末尾。此方法将anObject参数传递给每个isEqual:消息。如果isEqual:(在NSObject协议中声明)返回YES,则对象被视为相等。
您应该始终阅读文档:正如上面引用的摘录所指出的,这些细节通常在方法文档的"讨论"或"特别考虑"部分或类文档本身的"概述"部分中进行解释
这在整个Cocoa中的一致性如何(即NSArray的indexofObject:工作相同吗?)
它是一致的,但同时又不是。我的意思是,有两种方法可以使用:isEqual
和hash
。你不应该太在意什么时候用。相反,您应该关注的是尊重NSObject
协议要求,并确保如果两个对象根据isEqual
相等,那么它们也具有相同的哈希。
来自NSObject
协议参考中的isEqual
文档
如果两个对象相等,则它们必须具有相同的哈希值。这如果您在子类,并打算将该子类的实例放入收集确保您也在子类中定义了hash。