0

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

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

是吗?

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

在我看来,“默认”实现是简单地比较对象的指针而不是它的成员。我在这里正确吗?它甚至比 C++ 标准比较差。这就是我要验证的。

在我看来,如果我们的类是 NSObject 的直接子类,那么 isEqual 将简单地称它为父类的 isEqual 并简单地比较指针。

我在这里正确吗?我只是想确定一下。

4

3 回答 3

2

我认为NSObject' 的实现会进行指针比较,而 SDK 中的各种其他类会做最合适的事情,即。NSString对字符串内容进行比较,NSArray比较内容相等性等等。如果你想为你的自定义对象定义“更好的”相等性,你必须决定语义并自己实现它。

于 2012-10-21T08:35:03.927 回答
2

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

@protocol NSObject

- (BOOL)isEqual:(id)object;

这是实现的必需方法,因此 NSObject(类)肯定实现了这一点,尽管您不会通过查看苹果开发网站上的类定义来知道它。这直接来自 xcode 中的标题。

通常,如果不实现自定义 isEqual,您只会期望获得指针标识,并且在许多情况下没问题。系统需要围绕您识别唯一实例的方式进行设计,而不管哈希和 isEqual 等特定功能的特性如何。如果您需要测试指针之外的对象相等性,那么您只需要这样做。

于 2012-10-21T09:28:18.777 回答
1

作为NSObjectprovide isEqual:,并且您的所有对象都是 的后代NSObject,那么简单的答案是提供了默认实现。

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

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

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

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

在我键入时进行编码,预计会出现错误!只有重要的部分包括:

@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 一点。

于 2012-10-21T19:20:15.183 回答