== 比較兩個(gè)對(duì)象的內(nèi)存地址
isEqualToString: 比較兩個(gè)字符串的內(nèi)容
isEqual: 默認(rèn)情況下是比較兩個(gè)對(duì)象的內(nèi)存地址咕宿,但是有一些系統(tǒng)自帶的類(比如Foundation中的NSString,NSArray等)重寫了這個(gè)方法圆存,改變了這個(gè)方法的判斷規(guī)則(一般改為比較兩個(gè)對(duì)象的內(nèi)容,不是內(nèi)存地址)
數(shù)組NSArray中的containsObject:,indexOfObject:方法就是利用isEqual來(lái)比較的,所以數(shù)組中的字符串內(nèi)容一樣,也會(huì)被認(rèn)為是一樣的
- (void)test1
{
NSString *string1 = @"jack";
NSString *string2 = [NSString stringWithFormat:@"jack"];
//理論上存儲(chǔ)在內(nèi)存不同區(qū)域,為不同對(duì)象,但系統(tǒng)重寫后改成了比較內(nèi)容
NSLog(@"%p %p", string1, string2);
NSLog(@"string1 == string2 -> %zd", string1 == string2); // 結(jié)果為0
NSLog(@"[string1 isEqualToString:string2] -> %zd", [string1 isEqualToString:string2]); // 結(jié)果為1
NSLog(@"[string1 isEqual:string2] -> %zd", [string1 isEqual:string2]); // 結(jié)果為1
}
同理下面的兩個(gè)數(shù)組并不是同一個(gè),但是內(nèi)容相同,因此會(huì)被判定為相同
- (void)test2
{
NSString *string1 = [NSString stringWithFormat:@"111"];
NSString *string2 = [NSString stringWithFormat:@"222"];
//兩個(gè)存儲(chǔ)不同對(duì)象的數(shù)組,但內(nèi)容是相同的
NSArray *array1 = @[string1, @"222", @"333"];
NSArray *array2 = @[@"111", string2, @"333"];
NSArray *array = @[array1, array2];
NSLog(@"%zd", [array indexOfObject:array2]);//結(jié)果為0
}
如果有兩個(gè)內(nèi)容相同的MYPerson對(duì)象,則會(huì)被認(rèn)為是不同的,因?yàn)榇藭r(shí)是對(duì)內(nèi)存地址進(jìn)行比較,看是不是同一個(gè)對(duì)象
//沒(méi)有重寫isEqual
- (void)test3
{
MYPerson *p1 = [[MYPerson alloc] init];
p1.age = 20;
p1.no = 30;
MYPerson *p2 = [[MYPerson alloc] init];
p2.age = 20;
p2.no = 30;
NSLog(@"%p %p", p1, p2);
NSLog(@"p1 == p2 -> %zd", p1 == p2); // 0
NSLog(@"[p1 isEqual:p2] -> %zd", [p1 isEqual:p2]); // 0
}
如果希望MYPerson也能像系統(tǒng)的類NSString一樣,能夠?qū)?nèi)容相同的兩個(gè)不同對(duì)象也認(rèn)定為相同,需要重寫isEqual方法
//重寫后
- (void)test3
{
MYPerson *p1 = [[MYPerson alloc] init];
p1.age = 20;
p1.no = 30;
MYPerson *p2 = [[MYPerson alloc] init];
p2.age = 20;
p2.no = 30;
NSArray *array = @[@"2", @"6", p1, @"111"];
NSLog(@"%zd", [array indexOfObject:p2]);//結(jié)果為2
}
MYPerson中重寫代碼如下:
#import <Foundation/Foundation.h>
@class MYCar;
@interface MYPerson : NSObject
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, assign) NSInteger no;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, strong) MYCar *car;
- (BOOL)isEqualToPerson:(MYPerson *)person;
@end
#import "MYPerson.h"
#import "MYCar.h"
/*
一旦重寫了isEqual:方法恩掷,最好重寫hash方法,而且要遵守以下原則:
1.isEqual:返回YES的2個(gè)對(duì)象糟秘,hash值一定要一樣
2.hash值一樣的2個(gè)對(duì)象黔攒,isEqual:返回不一定是YES
*/
@implementation MYPerson
- (NSUInteger)hash
{
return self.age + self.no + self.name.hash + self.car.hash;
}
- (BOOL)isEqual:(MYPerson *)object
{
return [self isEqualToPerson:object];
}
- (BOOL)isEqualToPerson:(MYPerson *)person
{
// 如果是完全相同的對(duì)象,就省去后面的判斷
if (self == person) return YES;
// 如果object的類型不對(duì)舶斧,就不需要比較
if (![person isKindOfClass:self.class]) return NO;
// 基本數(shù)據(jù)類型
BOOL result = (self.age == person.age && self.no == person.no);
if (result == NO) return result;
// 對(duì)象類型,兩個(gè)對(duì)象為nil時(shí)isEqual:的結(jié)果為0(NO),所以需要專門處理
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