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
,这样才能工作
- 从:
- 从:
- 这种行为在Cocoa中的各种容器类中是一致的。例如,从:
您应该始终阅读文档:正如上面引用的摘录所指出的,这些细节通常在方法文档的“讨论”或“特别注意事项”部分或类文档本身的“概述”部分进行解释。这在整个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可以是