@""到底是什么?在幕后做什么?

时间:2015-12-13 19:57:44

标签: ios objective-c macos

使用submit提供NSString值时,该缩写的确切含义是什么?我注意到,在应用程序中所有其他条件相同的情况下,使用= @""制作的全局NSString不需要@""在方法之外使用retain ,而NSString以任何其他方式给出一个值。

我发现这个问题完全无法检测,所以我感谢你的时间。

3 个答案:

答案 0 :(得分:1)

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

@"Hello"无法释放,因为它是一个文字字符串 - 它在构建时已写入程序,而不是在运行时分配。

答案 1 :(得分: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

enter image description here

答案 2 :(得分:1)

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

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

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

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

相关问题