什么时候需要重写isEqual方法 和 hash方法
isEqual:
- 当你的子类之间需要判断相等时,重写isEqual:方法
hash 方法:
- 如果你写的子类还需要添加到集合类型(NSDictionary,NSSet等)中去,hash方法也需要重写。
内部实现
- (BOOL)isEqual:(id)object {
if (self == object) {
return YES;
}
if (![object isKindOfClass:[Person class]]) {
return NO;
}
return [self isEqualToPerson:(Person *)object];
}
- (BOOL)isEqualToPerson:(Person *)person {
if (!person) {
return NO;
}
BOOL haveEqualNames = (!self.name && !person.name) || [self.name isEqualToString:person.name];
BOOL haveEqualBirthdays = (!self.birthday && !person.birthday) || [self.birthday isEqualToDate:person.birthday];
return haveEqualNames && haveEqualBirthdays;
}
- (NSUInteger)hash {
return [self.name hash] ^ [self.birthday hash];
}
== 和 isEqual 和 isEqualToString 的区别
- ==
- 比较两个对象的指针,若是字符串 对比的是首地址。
- isEqualToString
- 比较两个字符串的内容.
- isEqual:
- 默认情况下是比较两个对象的内存地址.
- 系统自带的类(NSString, NSArray 等)重写了这个方法,改变了这个方法的判断规则。 (一般改为比较两个对象的内容,不是内存地址)
为什么要有isEqual方法?
== 运算符只是简单地判断是否是同一个对象。
isEqual方法可以判断对象是否相同, 例如UIColor对象表示的color是否相同。
例子:
isEquel和hash的关系
重写对象的isEquel和Hash方法,在Hash方法中返回对象属性位运算符的hash值,在 isEquel方法中比较对象的hash值。
这样可以确保在NSSet这样的集合中,对象是否一致用对象属性hash NSDictionary值进行判断。
- (NSUInteger)hash{
return self.age.hash ^ self.name.hash;
}
- (BOOL)isEqual:(id)object{
return self.hash == [object hash];
}
Hash 方法在什么时候会被调用
Hash方法只在对象被添加至NSSet和设置NSDictionary的key时会调用.
NSSet 添加新成员时, 需要根据hash值来快速查找成员, 以保证集合中是否已经存在该成员 NSDictionary在查找key时, 也利用了key的hash值。