【问题标题】:What exactly does @"" do behind the scenes?@"" 在幕后究竟做了什么?
【发布时间】:2016-03-19 06:16:37
【问题描述】:

当使用= @""NSString 赋值时,这个简写到底是什么意思?我注意到,在应用程序中所有其他条件相同的情况下,使用@"" 制作的全局NSStrings 不需要在赋予它们该值的方法之外使用retain,而NSStrings 给出了任何其他方式的价值。

我发现这个问题完全无法搜索,因此感谢您抽出宝贵时间。

【问题讨论】:

标签: ios objective-c macos


【解决方案1】:

相关回答:Difference between NSString literals

简而言之,在程序的全局范围内编写@"" 时,它与编写"" 的作用相同:您指定的文字字符串将在编译时嵌入到您的二进制文件中,因此不能被释放在运行时。这就是您不需要releaseretain 的原因。 @ 只是告诉编译器从 C 字符串文字构造一个 NSString 对象。请注意,这种结构非常便宜,并且可能进行了大量优化。您可以点击链接查看此示例:

NSString *str = @"My String";
NSLog(@"%@ (%p)", str, str);

NSString *str2 = [[NSString alloc] initWithString:@"My String"];
NSLog(@"%@ (%p)", str2, str2);

产生这个输出:

2011-11-07 07:11:26.172 Craplet[5433:707] My String (0x100002268)
2011-11-07 07:11:26.174 Craplet[5433:707] My String (0x100002268)

注意相同的内存地址

编辑: 我自己做了一些测试,看这段代码:

static NSString *str0 = @"My String";

int main(int argc, const char * argv[]) {
    NSLog(@"%@ (%p)", str0, str0);

    NSString *str = @"My String";
    NSLog(@"%@ (%p)", str, str);

    NSString *str2 = [[NSString alloc] initWithString:@"My String"];
    NSLog(@"%@ (%p)", str2, str2);

    return 0;
}

将产生这个输出:

2015-12-13 21:20:00.771 Test[6064:1195176] My String (0x100001030)
2015-12-13 21:20:00.772 Test[6064:1195176] My String (0x100001030)
2015-12-13 21:20:00.772 Test[6064:1195176] My String (0x100001030)

此外,在使用调试器时,您可以看到使用文字时创建的实际对象实际上是 __NSCFConstantString 对象。 我认为与此相关的概念称为Class Clusters

【讨论】:

  • 请注意,具有相同的地址是工具的产物,不应依赖。比较字符串时不使用地址,请使用isEqual:isEqualToString: 方法。请参阅此处的“警告”部分:clang.llvm.org/docs/ObjectiveCLiterals.html
【解决方案2】:

Objective-C 是 C 的超集,这意味着您应该能够在其中编写 C 代码并使其工作。因此,编译器需要一种方法来区分 C 字符串(老式的字节系列)和 Objective-C NSString(Unicode 支持等)。这是使用@ 符号完成的,例如@"Hello"

@"Hello" 不能被释放,因为它是一个文字字符串——它是在构建时写入程序的,而不是在运行时分配的。

【讨论】:

    【解决方案3】:

    使用文字语法分配的字符串,即@驻留在可执行文件的数据段中的 c 字符串。它们仅在程序启动时分配一次,并且在程序退出之前永远不会释放。

    作为练习,你可以试试这个:

    NSString *str1 = @"Hello";
    NSString *str2 = @"Hello";
    NSLog("Memory Address of str1 : %p", str1);
    NSLog("Memory Address of str2 : %p", str2);
    

    两个日志语句将打印相同的地址,这意味着文字是常量字符串,其生命周期与程序的生命周期相同。

    【讨论】:

      猜你喜欢
      • 2012-07-23
      • 2016-09-10
      • 2023-03-15
      • 2012-10-17
      • 2021-06-04
      • 1970-01-01
      • 2018-07-30
      • 2019-10-06
      • 2021-01-01
      相关资源
      最近更新 更多