1.比較兩個(gè)變量鹤树,結(jié)果卻有不同:
NSString *string1 = @"123";
NSString *string2 = @"123";
// 比較兩個(gè)字符串的內(nèi)存地址,而且地址是指向變量的地址
NSLog(@"----%zd",string1 == string2);
// 比較兩個(gè)字符串的內(nèi)容
NSLog(@"----%zd",[string1 isEqualToString:string2]);
// 默認(rèn)比較兩個(gè)字符串的內(nèi)存地址逊朽,但是如果比較的兩個(gè)對(duì)象是foundation框架中的對(duì)象罕伯,則系統(tǒng)重寫(xiě)了isEqual方法,比較內(nèi)容
NSLog(@"----%zd",[string1 isEqual:string2]);
Person *person1 = [[Person alloc]init];
person1.name = @"123";
person1.age = 15;
Person *person2 = [[Person alloc]init];
person2.name = @"123";
person2.age = 15;
NSLog(@"++++%zd",[person1 isEqual:person2]);
對(duì)于==這種形式叽讳,我們易于理解追他,但為什么isEqualToString和isEqual會(huì)有不同呢?原因在于蘋(píng)果在底層做了優(yōu)化岛蚤,isEqualToString實(shí)質(zhì)上是重寫(xiě)了isEqual方法邑狸,例如以下所示:
Person *person1 = [[Person alloc]init];
person1.name = @"123";
person1.age = 15;
Person *person2 = [[Person alloc]init];
person2.name = @"123";
person2.age = 15;
NSLog(@"++++%zd",[person1 isEqual:person2]);
返回的結(jié)果就是NO,因?yàn)槲覀冏远x了Person這個(gè)類(lèi)并沒(méi)有重寫(xiě)isEqual這個(gè)方法涤妒,兩個(gè)對(duì)象比較的默認(rèn)還是內(nèi)存地址单雾。
2.那問(wèn)題又來(lái)了,如果我們想要比較Person的兩個(gè)對(duì)象內(nèi)容看是否形同,那如何辦到呢硅堆?示例代碼如下:
#import "XMGPerson.h"
#import "XMGCar.h"
/*
一旦重寫(xiě)了isEqual:方法屿储,最好重寫(xiě)hash方法,而且要遵守以下原則:
1.isEqual:返回YES的2個(gè)對(duì)象渐逃,hash值一定要一樣
2.hash值一樣的2個(gè)對(duì)象够掠,isEqual:返回不一定是YES
*/
@implementation XMGPerson
- (NSUInteger)hash
{
return self.age + self.no + self.name.hash + self.car.hash;
}
- (BOOL)isEqual:(XMGPerson *)object
{
return [self isEqualToPerson:object];
}
- (BOOL)isEqualToPerson:(XMGPerson *)person
{
// 如果是完全相同的對(duì)象,就省去后面的判斷
if (self == person) return YES;
// 如果object的類(lèi)型不對(duì)茄菊,就不需要比較
if (![person isKindOfClass:self.class]) return NO;
// 基本數(shù)據(jù)類(lèi)型
BOOL result = (self.age == person.age && self.no == person.no);
if (result == NO) return result;
// 對(duì)象類(lèi)型
if (self.name || person.name) {
if (![self.name isEqual:person.name]) return NO;
}
if (self.car || person.car) {
if (![self.car isEqual:person.car]) return NO;
}
return YES;
}
@end