8

当我allocinit两个NSString变量比较它们的指针时,它们是相同的。这是一个显示这一点的片段:

NSString *s1 = [[NSString alloc] initWithString:@"hello world"];
NSString *s2 = [[NSString alloc] initWithString:@"hello world"];

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

为什么都s1s2一样?

4

2 回答 2

14

这里发生了三件事:

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

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

第三,在幕后,initWithString:调用CFStringCreateCopy,您可能会发现它具有以下行为: 由于此例程用于创建不可变字符串,因此它具有优化。它只是调用CFRetain()并返回传入的相同对象。

感谢您提出非常有趣的问题。我很高兴弄清楚它。

于 2012-07-23T05:20:19.220 回答
0

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

文档

在源代码中创建字符串对象的最简单方法是使用 Objective-C 的 @"..." 构造:

NSString *temp = @"/tmp/scratch"; 请注意,以这种方式创建字符串常量时,您应该使用 UTF-8 字符。这样的对象是在编译时创建的,并且存在于程序的整个执行过程中。编译器使此类对象常量在每个模块的基础上都是唯一的,并且它们永远不会被释放,尽管您可以像处理任何其他对象一样保留和释放它们。您也可以像执行任何其他字符串一样将消息直接发送到字符串常量:

BOOL 相同 = [@"comparison" isEqualToString:myString];

于 2012-07-23T07:04:52.853 回答