NSDictionary的objectForKey:依赖于身份还是平等?



假设我有一个名为Person的对象,该对象具有属性socialSecurityNumber,并且当社会保障号码属性相等时,该类重写isEqual:方法以返回true。假设我已经把一堆Person的实例放到了一个NSDictionary中。

如果我现在实例化一个newPerson对象,它恰好与字典中已经存在的对象具有相同的社会保险号,并且我执行[myDictionary objectForKey:newPerson],它会使用isEqual:并返回YES,还是会比较指针并返回NO?

我知道我可以写一个简单的测试来找出答案,但我想了解objectForKey:是如何准确地在字典中找到匹配项的,以及这在整个Cocoa中的一致性(即NSArrayindexofObject:工作相同吗?)

NSDictionary的工作原理类似于哈希表。因此,它使用-hash-isEqual:在字典中查找与给定关键字相对应的对象。

因此,为了回答您对NSDictionary的问题,这使用了isEqual:,而不是指针比较。但是,除了isEqual:之外,您还应该在Person类上实现hash,这样才能工作。

  • 从NSDictionary类参考文档中:

字典中的键值对称为条目。每个条目由一个表示键的对象和另一个表示该键值的对象组成。在字典中,关键字是唯一的。也就是说,一个字典中没有两个键是相等的(由isEqual确定:)。

  • 根据isEqual:方法文档:

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

  • 这种行为在Cocoa中的各种容器类中是一致的。例如,从NSArrayindexOfObject:方法文档中:

从索引0开始,向数组的每个元素发送一条isEqual:消息,直到找到匹配项或到达数组末尾。此方法将anObject参数传递给每个isEqual:消息。如果isEqual:(在NSObject协议中声明)返回YES,则对象被视为相等。


您应该始终阅读文档:正如上面引用的摘录所指出的,这些细节通常在方法文档的"讨论"或"特别考虑"部分或类文档本身的"概述"部分中进行解释

这在整个Cocoa中的一致性如何(即NSArray的indexofObject:工作相同吗?)

它是一致的,但同时又不是。我的意思是,有两种方法可以使用:isEqualhash。你不应该太在意什么时候用。相反,您应该关注的是尊重NSObject协议要求,并确保如果两个对象根据isEqual相等,那么它们也具有相同的哈希。

来自NSObject协议参考中的isEqual文档

如果两个对象相等,则它们必须具有相同的哈希值。这如果您在子类,并打算将该子类的实例放入收集确保您也在子类中定义了hash。

相关内容

最新更新