如果已知两个受测对象是属于同一类,判断等同的方法:
- ==:直接进行双等号判断
- isEqual:isEqual判断是否相等
- isEqualToString:这是判断字符串是否相等
NSObject中协议声明判断对象的等同性方法:
- (BOOL)isEqual:(id)object;
-
+ (NSUInteger)hash;
上述两种方法默认实现是:当且仅当其“指针值”完全相等时,这个两个对象才相等。
如果isEqual判定两个对象相等,那么hash方法返回的“一定”同一个值;如果hash方法返回同一个值,isEqual“未必”会认为两者相等。
自定义对象重写isEqual方法
第一步 自定义一个判断类等同的方法 该类是:LPAlertObject
- (BOOL)isEqualAlertObject:(LPAlertObject *)object{
if (self == object) {
return YES;
}
if ([self class] != [object class]) {
return NO;
}
NSString *name;
LPAlertObject *alert = (LPAlertObject *)object;
if (![_name isEqualToString:object.name]) {
return NO;
}if (_age != alert.age) {
return NO;
}
return YES;
}
- 1.判断指针是否相等
- 2.判断所属类是否是同一类
- 3.判断每个属性是否相等
第二步 重写isEqual 方法
- (BOOL)isEqual:(id)object{
if([self class] == [object class])
return [self isEqualAlertObject:(LPAlertObject *)object];
else
return [super isEqual:object];
}
这两步就完成了自定义类的等同性判断方法
等同性判断的执行深度
在等同性判断方法中是否需要监测全部字段需要开发者自行定义,比如有的数据判断一个标志就可以判断是否相等,类似主键。
容器中可变类的等同性
- Collection: 把对象放入Collection之后不要改变其哈希码,collection会根据对象的哈希码分装成不同的“箱子数组”。如果存入了得哈希码再改变,这个存的数组就是“错误”的。解决:保证存入的对象的哈希码不再改变。慎重修改Collection的图片
- NSMutableSet:
1.arrayA = [1,2]; 存入Set,set内存的是(1,2)
2.arrayB = [1,2]; 存入Set,set内存的是(1,2)
注:set判断数组相等 就是不添加了
3.arrayC = [2]; 存入set,set内存的是(1,2),(2)
若:arrayC里面的数据改成arrayC = [1,2];
那:set内存的是(1,2),(1,2)
如:setB = [set copy]; setB里面存的(1,2)
set语义不允许存相等的变量,如果把对象存入set再改变其内容,后果难以预料。
总结
- 1.监测对象等同性,使用isEqual、hash双重判断。
- 2.相同对象具有相同的哈希码,哈希码相同的对象未必相同。
- 3.自定义对象的等同性,根据特殊属性判断,最后才选择判断所有属性值。
- 4.编写hash方法时,应该使用计算速度快、哈希码碰撞低的算法。