- 若想檢測物件的等同性,請提供
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會把各個物件按照其雜湊碼分裝到不同的“箱子陣列”中。