对默认的isEqual和hash实现感到困惑

时间:2016-04-13 08:43:49

标签: ios objective-c

我知道我可以覆盖hash和isEqual来检查2个实例的相等性。 Xcode具有默认代码段和doucument https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/ObjectComparison.html,如下所示

- (BOOL)isEqual:(id)other
{
    if (other == self) {
        return YES;
    } else if (![super isEqual:other]) { //WHAT is this line mean ?
        return NO;
    } else {
        return <#comparison expression#>;
    }
}

- (NSUInteger)hash
{
    return <#hash expression#>;
}

好的,

  1. other == self检查两个对象&#39;指针。

  2. 如果![super isEqual:other],这行是什么意思?如果超级对象不等于其他,返回NO?然后它将始终返回NO,步骤3将不会被执行。

  3. 我错了吗?

    感谢。

3 个答案:

答案 0 :(得分:2)

它是类层次结构中的典型实现,也就是说,如果您的类派生自具有自己有意义的isEqual:实现的超类。在这种情况下,让超类测试公共属性的相等性是明智的。如果公共部分不相等,则派生对象不可能相等。

如果您直接从NSObject派生,则不需要。

实际上,您还需要一个额外的步骤:

- (BOOL)isEqual:(id)other
{
    if (other == self) {
        return YES;
    } else if (![super isEqual:other]) {
        return NO;
    } else if (![other isKindOfClass:[MyClass class]]) {
        return NO; // comparing incompatible objects 
    } else {
        MyClass *myOther = (MyClass *) other;
        return <#compare between self and myOther#>;
    }
}

答案 1 :(得分:0)

Objective-C中的Hash和isEqual略有不同。 首先,NSObject使用方法isEqual:检查与另一个对象的相等性,并且基本上,如果两个对象共享一组共同的可观察属性,则它们可能等于另一个对象。

对象比较中的哈希是确定集合成员资格的额外步骤,这将加快您的操作速度。

这将解释一下hash和isEqual

  • 对象平等是可交换的([a isEqual:b] - &gt; [b isEqual:a])
  • 如果对象相等,那么它们的哈希值也必须相等([a isEqual:b] - &gt; [a hash] == [b hash])
  • 但是,反过来并不成立:两个对象的哈希值相等并不意味着它们的值相等。

我希望这会有所帮助。作为参考,您可以访问此链接http://nshipster.com/equality/

答案 2 :(得分:0)

让我们看一下类继承的一个例子:

@interface A : NSObject
@property (nonatomic, assign, readwrite) NSInteger fieldA;
@end 

@interface B : A
@property (nonatomic, assign, readwrite) NSInteger fieldB;
@end 

现在,如果要在A上实现相等性,那么您希望将其基于fieldA的相等性:

// A equality
- (BOOL)isEqual:(id)other {
   ... 

   return [self fieldA] == [other fieldA];
}

当您在B上实施相等时,您需要两个条件 - 首先您必须确保fieldA相等,然后您必须确保fieldB相等。

// B equality
- (BOOL)isEqual:(id)other {
   ... 

   return [super isEqual:other] && [self fieldB] == [other fieldB];
}

这正是[super isEqual:other]正在做的事情 - 它检查超类的等式要求,即fieldA

说实话,这个isEqual:模板并不是很好。它缺少一个最重要的事情,那就是类等式检查:

if (![other isMemberOfClass:[self class]]) {
   return NO;
}

只有当您从不混合不同类的实例时,才需要此检查。但是,当您开始将AB的实例放入同一个数组/字典等中时,在尝试将A的实例与B的实例进行比较时,您会崩溃