- 若想检测对象的等同性,请提供
isEqual:
与hash
方法- 相同的对象必须具有相同的哈希码,但是两个哈希码相同的对象却未必相同
- 不要盲目的逐个检测每条属性,而是应该依据具体需求来指定检查方案。
- 编写hash方法时,应该使用计算速度快而且哈希码碰撞几率低的算法。
1、isEqual
方法与==
区别
NSString *foo = @"Badger 123";
NSString *bar = [NSStringstringWithFormat:@"Badger %i", 123];
BOOL eaualA = (foo == bar); // NO
BOOL equalB = [foo isEqual: bar]; // YES
BOOL equalC = [foo isEqualToString: bar]; // YES
区别:
==
比较的是两个对象的指针本身,而不是其所指的对象。- NSObject协议中声明
isEqual
来判断对象等同性 - 某些特殊对象提供了特殊的“等同性判定方法”。例如
isEqualToString
,推荐使用此方法。
2、isEqual
、hash
方法
-(BOOL)isEqual:(id)object;
-(NSUInterger)hash;
NSObject对象中这两个方法的默认实现是:当且仅当“指针值”相等时,这两个对象才相等。
EOCPerson类的自定义覆写
-(BOOL)isEqual:(id)object {
// 1、检查指针是否相等
if (self == object) return YES;
// 2、判断类型是否相等
if ([self class] != [object class]) return NO;
// 3、判断属性是否相等
EOCPerson *otherPerson = (EOCPerson *)object
......
return YES;
}
/// 推荐hash方法的写法. YYAsyncLayer也是这种写法。
-(NSUInteger)hash {
NSUInteger firlstNameHash = [_firstName hash];
NSUInteger lastNameHash = [_lastName hash];
NSUnteger ageHash = _age;
return firstNameHash ^ lastNameHash ^ ageHash;
}
3、特定类具有等同性判定方法
无需检测参数类型,代码如下
// 覆写isEqual方法
-(BOOL)isEqual:(id)object{
if ([self class] == [object class]) {
return [self isEqualToPerson:(EOCPerson*)object];
}else {
return [super isEqual: object]
}
}
-(BOOL)isEqualToPerson:(EOCPerson*)otherPerson {
if (self == object) return YES;
if (![_firstName isEqualToString:otherPerson.firstName]) {
return NO;
}
... 其他属性判断
return YES;
}
4、等同性判定的执行深度
NSArray的深度等同性判定,特定类的主键字段判定。
5、容器中可变类的等同性
某个对象放入collection之后就不应该在改变哈希码。collection会把各个对象按照其哈希码分装到不同的“箱子数组”中。