【问题标题】:Why are these two NSString pointers the same?为什么这两个 NSString 指针相同?
【发布时间】:2012-07-21 07:04:08
【问题描述】:

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

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

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

为什么s1s2 是一样的?

【问题讨论】:

  • 在您的 if 语句中,您不是在比较指针,而是比较它们指向的数据,并且查看代码,我会说“hello world”100% 等于“hello world” .
  • @NSArray:不,这是指针比较。您需要发送消息(isEqual:isEqualToString:)来比较这些值。
  • @NSArray 他正在比较指针。比较对象需要使用“*s1 == *s2”(这对字符串没有意义——你不能在Objective-C中重载==)。正如@Josh 所指出的,字符串内容与-isEqualToString: 进行比较。如果内容匹配,它将返回 YES,即使您正在比较两个不同的实例。

标签: objective-c cocoa nsstring


【解决方案1】:

这里发生了三件事:

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

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

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

感谢您提出非常有趣的问题。我很高兴解决这个问题。

【讨论】:

    【解决方案2】:

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

    来自documentation

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-03
      • 2020-05-03
      • 1970-01-01
      • 2021-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多