关于objective c:为什么这两个NSString指针是一样的?

Why are these two NSString pointers the same?

当我和init的变量和对比它们的指针时,它们是一样的。这是一个滑稽的表演:

1
2
3
4
5
6
7
8
NSString *s1 = [[NSString alloc] initWithString:@"hello world"];
NSString *s2 = [[NSString alloc] initWithString:@"hello world"];

if (s1 == s2) {
    NSLog(@"==");
}else {
    NSLog(@"!=");
}

为什么是同样的?


这里有三件事:

首先,您要传递给initWithString:的两个相同的字符串文本将具有相同的起始地址。这是对常量数据的明显优化。

其次,当使用字符串嵌套alloc和init时,运行时执行优化,alloc调用实质上变成了no-op。这是使用NSPlaceholderString类完成的。这意味着你回到这里的指针将来自initWithString:,而不是alloc。

第三,在引擎盖下,initWithString:调用CFStringCreateCopy,正如您可能发现的,它具有以下行为:因为这个例程是用于创建不可变字符串的,所以它有一个优化。它只调用CFRetain(),并返回传入的同一对象。

谢谢你这个有趣的问题。我很高兴弄明白了。


@"hello world"字符串属于NSConstantString类。如果在两个地方使用@"hello world",它们将引用非常相同的对象。

来自文档。

The simplest way to create a string object in source code is to use
the Objective-C @"..." construct:

NSString *temp = @"/tmp/scratch"; Note that, when creating a string
constant in this fashion, you should use UTF-8 characters. Such an
object is created at compile time and exists throughout your program’s
execution. The compiler makes such object constants unique on a
per-module basis, and they’re never deallocated, though you can retain
and release them as you do any other object. You can also send
messages directly to a string constant as you do any other string:

BOOL same = [@"comparison" isEqualToString:myString];