《Effective Ovjective-C 2.0》真心是一本可以帮助我更好理解OC语言的一本书,现在正在阅读中,作者在书中所提到的很多语法技巧和建议对我都很有帮助。遂在此将读书时的笔记和自己的理解整理与此。
对象等同性
“==”与“isEqual:”:
-
==
操作比较的是两个指针本身,而不是所指的对象。NSObject协议中声明的isEqual:
方法可以用来判断两个对象的等同性。 - NSString类实现了一个自己独有的的等同性判断方法
isEqualToString:
。传递给该方法的对象必须是NSString类型的,调用该方法比isEqual:
快,后者还要先判断对象的类型。
如果是自己定义的类:
Person *person1 = [[Person alloc] init];
Person *person2 = [[Person alloc] init];
使用isEqual:
方法判断:
NSLog(@"\nisEqual == %d", [person1 isEqual:person2]);
得到结果:
2016-03-24 15:44:39.189 Property_Demo[56504:3135972]
isEqual == 0
如果是系统框架提供的类:
NSArray *arr1 = [NSArray arrayWithObjects:person1, nil];
NSArray *arr2 = [NSArray arrayWithObjects:person1, nil];
NSLog(@"\nisEqual == %d", [arr1 isEqual:arr2]);
得到结果:
2016-03-24 15:50:16.027 Property_Demo[56691:3146107]**
isEqual == 1**
自己定义的类可以重写isEqual:
方法,通常,如果两个对象的所有属性都相等,那么就可以认为两个对象就想等,判断思路可以为:
- 是否相同指针(object1 == object2)
- 是否同一类型([object1 class] == [object2 class])
- 每个属性是否相同
也可以为自己的类编写自己的等同性判定方法,同时,也应一并覆写isEqual:
方法:
- (BOOL)isEqualToPerson:(Person *)anotherPreson {
if (self == anotherPreson) {
return YES;
}
if (![_firstName isEqualToString:anotherPreson.firstName]) {
return NO;
}
if (![_lastName isEqualToString:anotherPreson.lastName]) {
return NO;
}
if (_age != anotherPreson.age) {
return NO;
}
return YES;
}
- (BOOL)isEqual:(id)object {
if ([self class] == [object class]) {
return [self isEqualToPerson:(Person *)object];
} else {
return [super isEqual:object];
}
}
isEqual和hash:
- 若
isEqual:
为真,则必须具有相同的哈希码; - 若
hash
相同,则未必isEqual:
为真;
在NSSet中,根据对象的hash码为对象分组(相同的hash码作为一个数组),在向set添加对象时,若在set中无该hash码所对应的数组,则该set中一定没有这个对象。若set中有该hash码所对应的数组,那么遍历这个数组中的对象,看该数组中是否有和将要添加的对象相同的对象。因此:
- 如果hash码不同,
isEqual:
强制放回YES,则可以被添加到set中; - 如果将某一类的对象返回相同的hash码,则在向set添加对象时会降低效率。
判断等同性的执行深度(deep equality)
NSArray与NSDictionary也有对应的等同性判定方法,前者为isEqualToArray:
,后者为isEqualToDictionary:
,如果传入对象不是数组或字典,那么这两个方法会抛出异常。
NSArray的检测方式:先检查所对比数组个数,若相等,则使用isEqual对比两个数组中相对应位置的对象,如果均相等,则判定两个数组是相等的。
然而是否要在等同性判定方法中逐条检测全部字段或全部对象,要是具体情况而定。