在C中有一个相等运算符的默认实现。遍历所有成员并验证它们是否满足相等运算符。默认值有些愚蠢,因为如果一个对象包含指针,那么该成员的相等运算符将在指针上执行。
不过,这对我的目的来说已经足够了。
那么呢?
或者我们希望每次创建一个我们可能想要使用的自定义对象时实现isEqual和相应的哈希值。
在我看来,“默认”实现只是简单地比较对象的指针而不是它的成员。我在这里纠正吗?它比C ++标准比较更糟糕。这就是我想要验证的内容。
在我看来,如果我们的类是NSObject的直接子节点,那么isEqual将简单地调用它的父节点isEqual并且只是比较指针。
我在这里纠正吗?我只是想确保这一点。
答案 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:
可能使用的三种算法:
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。