@“”和@“123”之间有什么不同?

当我testing方法“retainCount”时,我遇到了一个问题,如下所示:

NSString *s_afmt0 = [[NSString alloc] initWithFormat:@""]; //-1 NSString *s_afmt1 = [[NSString alloc] initWithFormat:@"123"]; //1 NSLog(@"s_afmt0:%d", [s_afmt0 retainCount]); NSLog(@"s_afmt1:%d", [s_afmt1 retainCount]); 

结果:s_autf0:-1 s_autf1:1我不知道为什么? 为什么s_afmt0的retainCount是-1,s_autf1的retainCount是1.“@”和@“123”之间有什么区别? 任何人都可以解释 谢谢

你打印的是一个有符号整数的retainCount,实际上它是一个无符号整数(键入NSUInteger格式说明符为%u ,而不是%d )。 -1相当于UINT_MAX ,意味着对象没有retainCount。 NSString很可能已经认识到给定的string是不可变的,并且把指针指定给static @“”空的NSString,而不是把它放在堆上。

事实上,你可以用下面的代码来确认:

 NSString* str1 = [[NSString alloc] initWithFormat:@""]; NSString* str2 = [[NSString alloc] initWithFormat:@""]; NSLog(@"string1: %p, string2: %p", str1, str2); 

上面的代码应该为str1和str2打印相同的指针地址,这证实了我的理论,即NSString优化了这个特定的情况,事实上它确实:

 06:46:30.142 StringTest[45214:303] string1: 0x7fff7d8acf90, string2: 0x7fff7d8acf90 

那么让我们看看这是否是特定于NSString。 应该是,否则所有初始化为空string的NSMutableString对象将指向相同的内存!

 NSMutableString* str1 = [[NSMutableString alloc] initWithFormat:@""]; NSMutableString* str2 = [[NSMutableString alloc] initWithFormat:@""]; NSLog(@"string1: %p, string2: %p", str1, str2); 

输出:

 06:53:36.688 StringTest[45278:303] string1: 0x10010a850, string2: 0x10010a890 

两个不同的内存位置。 所以你有它,基础框架中的一个整洁的小优化。 TIL

编辑:

正如bbum 指出的那样 ,你永远不应该依赖retainCount,这是一个例子,如果你这样做的话会出现问题

虽然你不应该使用retainCount ,但是你所看到的最可能的原因是空string@“”被编译器所特别处理,因为它是一个常见的文字。

另外,为什么你使用string格式的string文字? 我想这只是为了testing目的,但你应该只有:

 NSString *s_afmt0 = @""; // no need to use stringWithFormat here