前言
最近看了一道题
NSString *s1 = @"Hello world"; NSString *s2 = @"Hello world";请问 s1 == s2的返回值是YES还是NO?
, 相信很多童鞋的答案都是NO,可能大家认为s1、s2两个对象的地址不同,但是事实真的如此么?
为此特意写了一个demo来印证下:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *str1 = @"abc";
NSString *str2 = [NSString stringWithFormat:@"%@",@"abc"];
NSString *str3 = [[NSString alloc]initWithString:str1];
NSString *str4 = [NSString stringWithString:str1];
NSString *str8 = [[NSString alloc] initWithString:@"abc"];
NSString *str9 = [NSString stringWithString:@"abc"];
NSString *str5 = [str1 copy];
NSString *str6 = [str1 mutableCopy];
NSString *str7 = [NSString stringWithFormat:@"%@",@"abc"];
NSLog(@"str1: %p",str1);
NSLog(@"str2: %p",str2);
NSLog(@"str3: %p",str3);
NSLog(@"str4: %p",str4);
NSLog(@"str5: %p",str5);
NSLog(@"str6: %p",str6);
NSLog(@"str7: %p",str7);
NSLog(@"str8: %p",str8);
NSLog(@"str9: %p",str9);
NSLog(@"===============");
NSLog(@"str1 == str2 \t\t%@",(str1 == str2) ? @"YES" : @"NO");
NSLog(@"str1 Equal str2 \t%@",[str1 isEqualToString:str2] ? @"YES" : @"NO");
NSLog(@"str1 == str3 \t\t%@",(str1 == str3) ? @"YES" : @"NO");
NSLog(@"str1 == str4 \t\t%@",(str1 == str4) ? @"YES" : @"NO");
NSLog(@"str3 == str4 \t\t%@",(str4 == str3) ? @"YES" : @"NO");
NSLog(@"str2 == str6 \t\t%@",(str2 == str6) ? @"YES" : @"NO");
NSLog(@"str2 Equal str6 \t%@",[str2 isEqualToString:str6] ? @"YES" : @"NO");
NSLog(@"str2 == str7 \t\t%@",(str7 == str2) ? @"YES" : @"NO");
NSLog(@"%d",str2 == str7);
}
return ;
}
//LOGCAT如下
-- :: testEqual[:] str1:
-- :: testEqual[:] str2:
-- :: testEqual[:] str3:
-- :: testEqual[:] str4:
-- :: testEqual[:] str5:
-- :: testEqual[:] str6:
-- :: testEqual[:] str7:
-- :: testEqual[:] str8:
-- :: testEqual[:] str9:
-- :: testEqual[:] ===============
-- :: testEqual[:] str1 == str2 NO
-- :: testEqual[:] str1 Equal str2 YES
-- :: testEqual[:] str1 == str3 YES
-- :: testEqual[:] str1 == str4 YES
-- :: testEqual[:] str3 == str4 YES
-- :: testEqual[:] str2 == str6 NO
-- :: testEqual[:] str2 Equal str6 YES
-- :: testEqual[:] str2 == str7 YES
-- :: testEqual[:]
由此可以得出结论
Tips:
1. str1 是 直接使用字面量语法赋值的变量。所以,跟str8,str9是一样的,编译器都会执行同样的代码来生成对象。
- str3和str4,则都是根据一个已知的字符串变量来生成对象。其实就是比上面Tip1多了一个步骤、所以,
str3和str8,str4和str9地址是相同的
- str2和str7
[NSString stringWithFormat:@"%@",@"abc"]
都是格式化生成,地址也是相同的
扩展:
同理,如果新加一个str10,那它的地址应该跟str2,str7也是一样的NSString *str10 = [NSString stringWithFormat:@"%@",str1];
- str5
和str6[str1 copy]
[str1 mutableCopy]
这两个涉及到深浅拷贝,
str5是str1的浅拷贝,指针都指向相同的地址
str6是str1的深拷贝,等于重新创建了一个新的对象所以地址是不同的
因此
如果上面的问题换种问法,比如:
NSString *s1 = @"hello";
NSString *s2 = [[NSString alloc] initWithString:s1];
请问s1==s2的返回值?
或者
NSString *s1 = [NSString stringWithFormat:@"hello"];
NSString *s2 = [NSString stringWithFormat:@"hello"];
请问s1==s2的返回值?
答案也都是YES!
PS:
单说NSString,系统为我们提供了一个
isEqualToString:
方法,所以一般情况下来说,我们是不会使用
==
来判断两个NSString对象是否相等的。
==
和
isEqualToString:
有什么区别呢?
由上面的例子也可以看到,
str1 == str2 NO
str1 Equal str2 YES
isEqualToString:
应该是只比较了两个对象的值,不比较地址
而
==
则会比较两个对象的地址和值是否都相等
毕竟判断两个对象是否相等的条件是:
当且仅当其“指针值(pointer value)”完全相等时,这两个对象才相等
.