Apple是否提供isEqual的默认实现:

时间:2012-10-21 08:28:25

标签: objective-c cocoa nsobject

在C中有一个相等运算符的默认实现。遍历所有成员并验证它们是否满足相等运算符。默认值有些愚蠢,因为如果一个对象包含指针,那么该成员的相等运算符将在指针上执行。

不过,这对我的目的来说已经足够了。

那么呢?

或者我们希望每次创建一个我们可能想要使用的自定义对象时实现isEqual和相应的哈希值。

在我看来,“默认”实现只是简单地比较对象的指针而不是它的成员。我在这里纠正吗?它比C ++标准比较更糟糕。这就是我想要验证的内容。

在我看来,如果我们的类是NSObject的直接子节点,那么isEqual将简单地调用它的父节点isEqual并且只是比较指针。

我在这里纠正吗?我只是想确保这一点。

3 个答案:

答案 0 :(得分:2)

我认为NSObject的实现会进行指针比较,而SDK中的各种其他类做的最合适,即。 NSString对字符串内容进行比较,NSArray比较内容相等性,依此类推。如果您希望为自定义对象定义“更好”的相等性,则必须自行决定语义并自行实现。

答案 1 :(得分:2)

由于Apple在协议和接口之间分离文档的方式,它有点令人困惑。

@protocol NSObject

- (BOOL)isEqual:(id)object;

这是一个必须实现的方法,所以NSObject(该类)肯定会实现这个,尽管你不会通过查看apple dev网站上的类定义来了解它。这直接来自xcode中的标题。

一般情况下,如果没有实现自定义isEqual,您将期望只获得指针标识,并且在许多情况下都可以。系统需要围绕识别唯一实例的方式进行设计,而不管特定功能(如hash和isEqual)的特性如何。如果你需要测试超出指针的对象相等性,那么你就必须这样做。

答案 2 :(得分:1)

由于NSObject提供了isEqual:,并且您的所有对象都是NSObject的后代,所以简单的答案是提供默认实现。

现在你担心这个默认使用的算法,并在评论中写“我不确定只是通过测试”。让我们看看测试,只是为了好玩; - )

现在isEqual:是一种相当基本的方法,如果Apple决定改变它的语义,后果可能会很严重而且不好。因此,虽然Apple可以自由地改变它的实现方式,只要语义保持不变,这意味着相同的对象在更改之后与之前相同。现在您已经提到了isEqual:可能使用的三种算法:

  1. 指针比较 - 是完全相同的对象
  2. 浅比较 - 直接比较对象的字段
  3. 深度比较 - 直接比较的非指针值字段是否具有相同的值,并使用isEqual:
  4. 将指针值字段进行比较

    这些都有不同的语义,无论苹果选择了哪一个,它都无法在不破坏大量代码的情况下改变。不同的语义意味着你可以测试......

    我打字时编码,预计错误!只包括重要的部分:

    @implementation A
    
    - (BOOL) isEqual:(id)other
    {
       NSLog(@"A.isEqual called");
       return self == other; // true iff same object
    }
    
    @end
    
    @interface B
    
    @property (readwrite) int anInteger;
    @property (readwrite) A *anA;
    
    @end
    
    @implementation B
    
    @synthesize anInteger, anA;
    
    @end
    
    // Let's test the algorithm
    
    A *myA = [A new];
    B *bOne = [B new];
    B *bTwo = [B new];
    
    bOne.anInteger = 42;
    bOne.anA = myA;
    
    bTwo.anInteger = 42;
    bTwo.anA = myA;
    
    // What output is produced (all of it!)
    NSLog(@"[bOne isEqual:bTwo] -> %@", [bOne isEqual:bTwo] ? @"Yes" : @"No");
    

    HTH。