在比较期间,每次都不会调用覆盖isEqual方法

GJa*_*ain 4 objective-c ios

我有一个叫做的课

Contact;
Run Code Online (Sandbox Code Playgroud)

Contact我有(simple version to test, no hash yet)

- (BOOL)isEqual:(id)other {
    if (other == self)
        return YES;
    if (!other || ![other isKindOfClass:[self class]])
        return NO;
    return NO;
}
Run Code Online (Sandbox Code Playgroud)

我做:

NSMutableArray *arr = [[NSMutableArray alloc] init];
Contact *contact = [Contact new];
[arr addObject:contact]

// I expect my isEqual to be called here but it does not get called
[arr containsObject:contact] // this evaluates to true somehow!!!
Run Code Online (Sandbox Code Playgroud)

但是,如果我添加另一个要键入的对象NSString,则会调用它来比较String对象而不是联系对象.意思是

[arr addObject:@""] // so now arr has two elements

// here I expect two calls to isEqual but only one gets there
// when comparing string object against Contact
[arr containsObject:contact]
Run Code Online (Sandbox Code Playgroud)

为什么isEqual在我上面提到的情况下没有被调用?

Toa*_*tor 8

请阅读参考库中isEqual: NSObject协议中的讨论.

您会发现,对于集合内部的对象(例如NSArray),hash可能会用于确定两个对象是否实际相同.如果两个指针实际指向同一个对象,则无需检查是否相等 - 因此isEqual:永远不会被调用.

参考库建议的解决方案也是hash在子类中实现的.

  • 我怀疑在这种情况下涉及`-hash`方法."NSArray"不是基于散列的集合.另外,问题中的`-isEqual:`方法维护了` - [NSObject isEqual:]`的语义,所以继承的`-hash`就可以了.最后,如果两个对象相等,则它们的哈希值必须相同,但如果它们的哈希值相同而不暗示它们相等(哈希值与其性质相冲突).因此,即使`NSArray`使用了散列并发现两个相同,它仍然需要调用`-isEqual:`进行验证.可能的原因只是`NSArray`在`-isEqual:`之前检查指针相等性. (4认同)