《Effective Ovjective-C 2.0》真心是一本可以幫助我更好理解OC語言的一本書,現在正在閱讀中,作者在書中所提到的很多語法技巧和建議對我都很有幫助。遂在此將讀書時的筆記和自己的理解整理與此。
xiu!
對象等同性
“==”與“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對比兩個數組中相對應位置的對象,如果均相等,則判定兩個數組是相等的。
然而是否要在等同性判定方法中逐條檢測全部字段或全部對象,要是具體情況而定。