===: 比较两个对象的内存地址
isEqualToString: 比较两个字符串的内容
isEqual: 默认状况下是比较两个对象的内存地址, 可是有一些系统自带的类(好比Foundation中的NSString, NSArray等)重写了这个方法, 改变了这个方法的判断规则(通常改成比较两个对象的内容, 不是内存地址);
例如:数组NSArray中的containsObject:, indexOfObject: 方法就是利用isEqual来比较的, 因此数组中的字符串内容若是同样的话, 也会被认为是同样的;
复制代码
- (void)test1 {
NSString *string1 = @"jack";
NSString *string2 = [NSString stringWithFormat:@"jack"];
//理论是来讲,这两个字符串存储在内存的不一样区域, 为不一样的对象, 可是系统重写后改为了比较内容
NSLog(@"string1 -- %p\nstring2 --- %p",string1, string2);
//比较这两个对象的内存地址是否相等
if (string1 == string2) {
NSLog(@"string1 == string2");
}
else {
NSLog(@"string1 != string2");
}
//比较这两个对象的内容是否相等
if ([string1 isEqualToString:string2]) {
NSLog(@"string1 is equal to string2");
}
else {
NSLog(@"string1 is not equal to string2");
}
//比较这两个对象的内容是否相等
if ([string1 isEqual:string2]) {
NSLog(@"string1 is equal string2");
}
else {
NSLog(@"string1 is not equal string2");
}
}
输出内容:
string1 -- 0x10aab4ef0
string2 --- 0x8843f2a833eb3556
string1 != string2
string1 is equal to string2
string1 is equal string2
复制代码
下面两个数组并非同一个,可是内容相同, 所以会被断定为相同数组
- (void)test2 {
NSString *string1 = [NSString stringWithFormat:@"111"];
NSString *string2 = [NSString stringWithFormat:@"222"];
//两个存储不一样对象的数组, 但内容是相同的
NSArray *array1 = @[string1, @"222", @"333"];
NSArray *array2 = @[@"111", string2, @"333"];
//数组内容相同
NSLog(@"array1 --- %@",array1);
NSLog(@"array2 --- %@",array2);
//数组内存地址不一样
NSLog(@"array1 --- %p",array1);
NSLog(@"array2 --- %p",array2);
NSArray *array = @[array1, array2];
//输出结果为0, 由于array1 与 array2 是同样的
NSLog(@"index --- %zd",[array indexOfObject:array2]);
}
输出结果:
array1 --- (
111,
222,
333
)
array2 --- (
111,
222,
333
)
array1 --- 0x6000014813e0
array2 --- 0x600001481410
index --- 0
复制代码
若是有两个内容相同的MYPerson对象, 则会被认为是不一样的, 由于此时是对内存地址进行比较, 看是否是同一个对象;bash
//没有重写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(@"p1 --- %p",p1);
NSLog(@"p2 --- %p",p2);
if (p1 == p2) {
NSLog(@"p1 == p2");
}
else {
NSLog(@"p1 != p2");
}
if ([p1 isEqual:p2]) {
NSLog(@"p1 is equal p2");
}
else {
NSLog(@"p1 is not equal p2");
}
}
输出结果:
p1 --- 0x600000381aa0
p2 --- 0x600000381ad0
p1 != p2
p1 is not equal p2
复制代码
MYPerson.h文件
#import <Foundation/Foundation.h>
#import "MYCar.h"
NS_ASSUME_NONNULL_BEGIN
@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
MYPerson.m文件
#import "MYPerson.h"
@implementation MYPerson
- (NSUInteger)hash {
return self.age + self.no + self.name.hash + self.car.hash;
}
- (BOOL)isEqual:(id)object {
return [self isEqualToPerson:object];
}
- (BOOL)isEqualToPerson:(MYPerson *)person {
//若是是彻底相同的对象, 就省去后面的判断
if (self == person) return YES;
//若是object的类型不对, 就不须要比较
if (![person isKindOfClass:self.class]) return NO;
//基本数据类型
BOOL result = (self.age == person.age && self.no == person.no);
if (result == NO) return result;
//对象类型, 两个对象为nil时, isEqual的结果为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
复制代码
若是但愿MYPerson也能像系统的类NSString同样, 可以对内容相同的两个不一样对象也认定为相同, 须要重写isEqual方法:ui
//重写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(@"p1 --- %p",p1);
NSLog(@"p2 --- %p",p2);
//内存地址不一样
if (p1 == p2) {
NSLog(@"p1 == p2");
}
else {
NSLog(@"p1 != p2");
}
//内容相同
if ([p1 isEqual:p2]) {
NSLog(@"p1 is equal p2");
}
else {
NSLog(@"p1 is not equal p2");
}
}
复制代码
MYPerson中重写的代码以下:atom
MYPerson.h文件
#import <Foundation/Foundation.h>
#import "MYCar.h"
NS_ASSUME_NONNULL_BEGIN
@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
NS_ASSUME_NONNULL_END
MYPerson.m文件
#import "MYPerson.h"
/*
一旦重写了isEqual:方法, 最好重写hash方法, 并且要遵照如下原则:
1: isEqual: 返回YES的2个对象, hash值必定要同样
2: hash 值同样的2个对象, isEqual: 返回不必定是YES
*/
@implementation MYPerson
- (NSUInteger)hash {
return self.age + self.no + self.name.hash + self.car.hash;
}
- (BOOL)isEqual:(id)object {
return [self isEqualToPerson:object];
}
- (BOOL)isEqualToPerson:(MYPerson *)person {
//若是是彻底相同的对象, 就省去后面的判断
if (self == person) return YES;
//若是object的类型不对, 就不须要比较
if (![person isKindOfClass:self.class]) return NO;
//基本数据类型
BOOL result = (self.age == person.age && self.no == person.no);
if (result == NO) return result;
//对象类型, 两个对象为nil时, isEqual的结果为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
复制代码
原文: blog.csdn.net/qq_23892379…spa