当我alloc
和init
两个NSString
变量并比较它们的指针时,它们是相同的。这是一个显示以下内容的片段:
NSString *s1 = [[NSString alloc] initWithString:@"hello world"];
NSString *s2 = [[NSString alloc] initWithString:@"hello world"];
if (s1 == s2) {
NSLog(@"==");
}else {
NSLog(@"!=");
}
为什么s1
和s2
相同?
答案 0 :(得分:14)
这里有三件事:
首先,您传递给initWithString:
的两个相同的字符串文字将具有相同的地址。这是对常数数据的明显优化。
其次,当您使用字符串嵌套alloc和init时,运行时执行优化,alloc调用基本上变为无操作。这是使用NSPlaceholderString
类完成的。这意味着您返回此处的指针将来自initWithString:
,而不是来自alloc。
第三,在引擎盖下,initWithString:
正在调用CFStringCreateCopy
,正如您所知,它具有以下行为:由于此例程用于创建不可变字符串,因此它具有优化。它只是调用CFRetain()
并返回传入的相同对象。
感谢非常有趣的问题。我玩得很开心。
答案 1 :(得分:0)
@“hello world”字符串属于类NSConstantString
。如果你在两个地方使用@“hello world”,它们将引用同一个对象。
在源代码中创建字符串对象的最简单方法是使用 Objective-C @“...”构造:
NSString * temp = @“/ tmp / scratch”;请注意,创建字符串时 以这种方式保持不变,你应该使用UTF-8字符。这样的 对象是在编译时创建的,并且存在于整个程序中 执行。 编译器使这样的对象常量唯一 每个模块的基础,它们永远不会被释放,尽管你可以保留 并在执行任何其他对象时释放它们。你也可以发送 消息直接发送到字符串常量,就像执行任何其他字符串一样:
BOOL same = [@“comparison”isEqualToString:myString];