1.判斷對(duì)象是否相等的tip
- isEqual or ==
NSString *foo = @"Badger 123";
NSString *bar = [NSString stringWithFormat:@"Badger %i", 123];
BOOL equalA = (foo == bar); //< equalA = NO
BOOL equalB = [foo isEqual:bar]; //< equalB = YES
BOOL equalC = [foo isEqualToString:bar]; //< equalC = YES
isEqual方法來(lái)自于NSObject協(xié)議,有時(shí)等號(hào)不能解決的問(wèn)題,可以通過(guò)重寫(xiě)isEqual方法來(lái)自定義實(shí)現(xiàn)。
其內(nèi)部原理在于可以通過(guò)計(jì)算每一個(gè)object的hash值來(lái)判斷兩個(gè)object是否相等。
- (NSUInteger)hash;
而hash的計(jì)算是一件耗時(shí)工作,因此如果可以不需要計(jì)算hash,而是通過(guò)計(jì)算每個(gè)對(duì)象的identifier值則也可以達(dá)到目的。
當(dāng)然需要在定義class時(shí),并添加identifier屬性,和比較方法
@property NSUInteger identifier;
2)相等性判斷在集合中使用中的作用
已知集合是不允許有重復(fù)元素的,但有時(shí)當(dāng)我們?cè)诩现刑砑涌勺償?shù)組,卻可以出現(xiàn)集合中含有的元素一樣的情況,參考以下代碼:
NSMutableSet *set = [NSMutableSet new];
NSMutableArray *arrayA = [@[@1, @2] mutableCopy];
[set addObject:arrayA];
NSLog(@"set = %@", set);
// Output: set = {((1,2))}
NSMutableArray *arrayB = [@[@1, @2] mutableCopy];
[set addObject:arrayB];
NSLog(@"set = %@", set);
// Output: set = {((1,2))}
可以看到上面這種方式添加集合中的元素不會(huì)實(shí)現(xiàn)出現(xiàn)集合中元素有一致的情況
但如果這樣操作就可以了!
NSMutableArray *arrayC = [@[@1] mutableCopy];
[set addObject:arrayC];
NSLog(@"set = %@", set);
// Output: set = {((1),(1,2))}
[arrayC addObject:@2];
NSLog(@"set = %@", set);
// Output: set = {((1,2),(1,2))}
這樣就實(shí)現(xiàn)了集合set中存有兩個(gè)一樣的元素了。當(dāng)然這個(gè)問(wèn)題是為了引發(fā)別的思考,既然我們可以實(shí)現(xiàn)集合中存在一樣的元素,但是不能保證集合在拷貝后一樣維持原來(lái),當(dāng)然也不可能維持原來(lái),這就是我們?cè)谧黾蟽?nèi)相等比較判斷時(shí)需要注意的問(wèn)題!
1. 如果想比較兩個(gè)object是否相等,請(qǐng)實(shí)現(xiàn)isEqual:和hash兩種方法
2. 兩個(gè)對(duì)象相等,一定含有同樣的hash值;但是含有同樣哈希值的兩個(gè)對(duì)象卻不一定相等
3. 巧妙地設(shè)計(jì)比較方法(比如identifier),比簡(jiǎn)單直接比較所有屬性更有意義
4. 雖然為了實(shí)現(xiàn)絕對(duì)唯一性,hash方法可以設(shè)計(jì)的很復(fù)雜,但是出于性能考慮,適當(dāng)?shù)亓粲衕ash沖突也是必要的