Objective c 美国国家科学院词典';s objectForKey:依赖身份还是平等?

Objective c 美国国家科学院词典';s objectForKey:依赖身份还是平等?,objective-c,cocoa-touch,cocoa,foundation,Objective C,Cocoa Touch,Cocoa,Foundation,假设我有一个名为Person的对象,该对象具有属性socialSecurityNumber,当社会保险号码属性相等时,该类重写isEqual:方法以返回true。假设我已经把一堆Person的实例放到NSDictionary中 如果我现在实例化一个newPerson对象,该对象恰好与字典中已有的对象具有相同的社会保险号,并且我执行[myDictionary objectForKey:newPerson],它会使用isEqual:并返回YES,还是会比较指针并返回NO 我知道我可以编写一个简单的测

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

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


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

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

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

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

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

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


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

这在整个Cocoa中是多么一致(即NSArray的indexofObject:是否工作相同?)

它是一致的,但同时又不一致。我的意思是,有两种方法可以使用:
isEqual
hash
。您不应该太在意何时使用哪个。相反,您应该关注的是尊重
NSObject
协议要求,并确保两个对象根据
isEqual
它们也具有相同的散列

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


只要两个相等的对象具有相同的散列,并且散列不会太复杂而无法计算。用于该操作的算法由您决定,但具有不同散列值的两个对象将始终被视为不同的,具有相同散列值的两个对象将被视为可能相等,并将调用
isEqual:
以确保它们确实相等。这允许通过仅比较哈希值(仅为整数)进行非常快速的比较和字典查找,并且仅在哈希相等时才与
isEqual:
进行真正的比较。例如,对于一个字符串,可以通过返回字符串的长度来实现
hash
方法。两个相等的字符串将具有相同的哈希,两个不同的字符串将具有不同的哈希值。有些字符串是不同的(如
@“bar”
@“baz”
)仍将具有相同的哈希值,但这不是问题,在这种情况下,
isEqual:
将逐字符进行更深入的分析以检查是否相等。但这(更耗时)比较仅用于比较相同长度的字符串:具有不同长度的字符串将更快地返回
NO
。请注意,也可以通过始终返回
0
来实现
hash
。例如:它仍然符合hash函数的要求,但由于所有对象都具有相同的hash,因此所有比较将触发对
isEqual:
的调用。当然,即使这样做可行,这在性能方面也将是一场灾难,因为在这种情况下,每次都会进行深入比较。在实现
哈希时,一切都是一个折衷的问题,在一个易于计算但也会分布var的哈希之间为了利用这种机制,可以为不同的对象均匀地分配散列值。非常好的解释,谢谢。但是我应该覆盖哪个方法来实现散列检查?文档中所述的
hash
方法。两条注释:一条,NSArray有第二个方法“IndexofObjectIndentialTo:”找到相同的对象,即相同的对象指针。包含“foo”的两个不同NSString*对象将被视为不同。第二,哈希和isEqual的默认实现:使用指针作为哈希键并比较指针。例如,NSWindow/UIWindow可以是