1. ==运算符
- 当比较类型为基本类型时,==比较它们的值,值相等返回YES。
- 当比较类型为指针类型(包括对象)时,==比较它们的地址值,地址值相等返回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