判断对象是否相等的方法,==与 isEqual


  • == 比较两个对象的内存地址

  • isEqualToString: 比较两个字符串的内容

  • isEqual: 默认情况下是比较两个对象的内存地址,但是有一些系统自带的类(比如Foundation中的NSString,NSArray等)重写了这个方法,改变了这个方法的判断规则(一般改为比较两个对象的内容,不是内存地址)

数组NSArray中的containsObject:,indexOfObject:方法就是利用isEqual来比较的,所以数组中的字符串内容一样,也会被认为是一样的

- (void)test1
{
   NSString *string1 = @"jack";
   NSString *string2 = [NSString stringWithFormat:@"jack"];

//理论上存储在内存不同区域,为不同对象,但系统重写后改成了比较内容
   NSLog(@"%p %p", string1, string2);

   NSLog(@"string1 == string2 -> %zd", string1 == string2); // 结果为0

   NSLog(@"[string1 isEqualToString:string2] -> %zd", [string1 isEqualToString:string2]); // 结果为1

   NSLog(@"[string1 isEqual:string2] -> %zd", [string1 isEqual:string2]); // 结果为1

}

同理下面的两个数组并不是同一个,但是内容相同,因此会被判定为相同

- (void)test2
{
    NSString *string1 = [NSString stringWithFormat:@"111"];
    NSString *string2 = [NSString stringWithFormat:@"222"];
    //两个存储不同对象的数组,但内容是相同的
    NSArray *array1 = @[string1, @"222", @"333"];
    NSArray *array2 = @[@"111", string2, @"333"];
    
    NSArray *array = @[array1, array2];
    
    NSLog(@"%zd", [array indexOfObject:array2]);//结果为0
}

如果有两个内容相同的MYPerson对象,则会被认为是不同的,因为此时是对内存地址进行比较,看是不是同一个对象

//没有重写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也能像系统的类NSString一样,能够对内容相同的两个不同对象也认定为相同,需要重写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]);//结果为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个对象,hash值一定要一样
 2.hash值一样的2个对象,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
{
    // 如果是完全相同的对象,就省去后面的判断
    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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容

  • 前言 对数据的等同性判断包括对基本数据类型等同性的判断和对象等同性的判断。对基本数据类型等同性的判断是非常简单的,...
    VV木公子阅读 1,406评论 0 8
  • 1、从理论上讲,根本没有“当下”这样一个概念,因为你“现在”经历的每一瞬间,都马上会变成“过去”的那一瞬间。 2、...
    楠神锅锅阅读 750评论 0 1
  • 心中有集体,脑中有理智,看到即去行动。女人或男人,心胸狭窄又自私是可卑的(卑鄙无耻)!
    雾莲阅读 107评论 1 0
  • 无需讳言,不少公司采用的是“机会主义战略”,通过扑捉市场机会,获得了阶段性的增长。不愿化大力气培育核心竞争力,也不...
    南山行者369阅读 439评论 0 1
  • 为你说 你是我心中一个白发苍苍的梦想 你是我陆里海里漂洋的港 你是细语万千 你是骄阳艳艳 你是我人山人海中的一睁眼...
    夏三三阅读 202评论 0 2