【OC】==和isEqual方法

1. ==运算符

  1. 当比较类型为基本类型时,==比较它们的值,值相等返回YES。
  2. 当比较类型为指针类型(包括对象)时,==比较它们的地址值,地址值相等返回YES。

例:

#import <Foundation/Foundation.h>

int main(void) {
    @autoreleasepool {
        int num1 = 0;
        int num2 = 0;
        int* per1 = &num1;
        int* per2 = &num2;
        NSLog(@"%d", num1 == num2);
        NSLog(@"%d", per1 == per2);
    }
}

结果:

2022-05-25 20:43:06.551271+0800 oc.programme[84088:2947719] 1
2022-05-25 20:43:06.551289+0800 oc.programme[84088:2947719] 0

值得注意的是,当Objective-C程序直接使用如@"hello"的字符直接量时,系统将会使用常量池来管理这些字符串。常量池保证字符串直接量只有一个,不会产生多个副本。
例:

int main(void) {
    @autoreleasepool {
        NSString* str1 = @"hello word";
        NSString* str2 = @"hello word";
        NSString* str3 = @"hello user";
        NSLog(@"%d", str1 == str2);
        NSLog(@"%d", str1 == str3);
    }
}

在上例中,str1和str2指向同一个字符串直接量,str3指向不同的字符串直接量。
输出:

2022-05-25 20:43:06.551271+0800 oc.programme[84088:2947719] 1
2022-05-25 20:43:06.551289+0800 oc.programme[84088:2947719] 0

2. isEqual方法

isEqual方法是NSObject提供的一个实例方法,该方法默认比较对象的地址,即运行结果与==运算符相同。通常,我们需要重写isEqual方法,自定义相等标准

2.1 NSString已经重写了isEqual方法,该方法比较字符串的字符序列。

例:

int main(void) {
    @autoreleasepool {
        NSString* str1 = [NSString stringWithFormat:@"hello word"];
        NSString* str2 = [NSString stringWithFormat:@"hello word"];
        NSLog(@"%d", (str1 == str2));
        NSLog(@"%d", [str1 isEqual:str2]);
    }
}

输出:

2022-05-25 21:05:48.171439+0800 oc.programme[84316:2958152] 0
2022-05-25 21:05:48.171648+0800 oc.programme[84316:2958152] 1

使用stringWithFormat:类方法创建的字符串是运行时创建出来的,它被保存在堆内存中,不会放入常量池,因此上例中str1与str2保存的地址值不同。
需要注意的是时代在进步,在现在使用stringwithFormat:类方法创建字符串,当在字符串长度小于等于一个特定值且无特殊字符时,上例情况不会发生,即str1和str2保存的地址值相同。这个特定值通常是9,在含字母q是7。具体原因我也不懂,请查询NSString的三种类型

2.2 重写isEqual

我们可以为我们的类重写isEqual方法,得到我们理想的相等判断条件。
例:

#import <Foundation/Foundation.h>

@interface Brid : NSObject
@property (nonatomic, assign) NSString* kind;
@property (nonatomic, assign) int age;
- (id) initWithKind:(NSString*) kind andAge:(int) age;
@end

@implementation Brid
- (id) initWithKind:(NSString *) kind andAge:(int) age {
    if (self = [super init]) {
        self.kind = kind;
        self.age = age;
    }
    return self;
}
- (BOOL) isEqual:(id) object {
    // 指的是同一个对象
    if (self == object) {
        return YES;
    } else {
        Brid* other = (Brid*)object;
        // 如果是同一种鸟则返回YES
        if (self.kind == other.kind) {
            return YES;
        } else {
            return NO;
        }
    }
}
@end

上面我们定义了鸟类,并重写了它的isEqual方法,如果是同一种鸟就返回YES。
测试:

int main(void) {
    @autoreleasepool {
        Brid* brid1 = [[Brid alloc] initWithKind:@"麻雀" andAge:3];
        Brid* brid2 = [[Brid alloc] initWithKind:@"麻雀" andAge:2];
        Brid* brid3 = [[Brid alloc] initWithKind:@"喜鹊" andAge:3];
        NSLog(@"%d", [brid1 isEqual:brid2]);
        NSLog(@"%d", [brid1 isEqual:brid3]);
    }
}

测试结果:

2022-05-25 21:36:32.195427+0800 oc.programme[84650:2970676] 1
2022-05-25 21:36:32.195636+0800 oc.programme[84650:2970676] 0
Program ended with exit code: 0
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值