你如何正确地覆盖isEqual:
在Objective-C?“陷阱”似乎是,如果两个对象相等(由isEqual:
方法确定),它们必须具有相同的哈希值。
可可基础指南的自省部分确实有一个关于如何覆盖名为MyWidget
的类的isEqual:
的示例,复制如下:
- (BOOL)isEqual:(id)other {
if (other == self)
return YES;
if (!other || ![other isKindOfClass:[self class]])
return NO;
return [self isEqualToWidget:other];
}
- (BOOL)isEqualToWidget:(MyWidget *)aWidget {
if (self == aWidget)
return YES;
if (![(id)[self name] isEqual:[aWidget name]])
return NO;
if (![[self data] isEqualToData:[aWidget data]])
return NO;
return YES;
}
它检查指针是否相等,然后是类是否相等,最后使用isEqualToWidget:
比较对象,它只检查name
和data
属性。例子不显示的是如何覆盖hash
。
让我们假设有其他不影响相等的属性,比如age
。难道不应该重写hash
方法,以便只有name
和data
影响哈希吗?如果是,你会怎么做?只需要添加name
和data
?例如:
- (NSUInteger)hash {
NSUInteger hash = 0;
hash += [[self name] hash];
hash += [[self data] hash];
return hash;
}
这足够了吗?有更好的技术吗?如果你有像int
这样的原语呢?将它们转换为NSNumber
以获得它们的散列?或者像NSRect
这样的结构?
(大脑屁:最初将它们与|=
一起写成“按位或”。意味着添加。)