这两种创建NSStrings的方法有什么区别?

ada*_*ame 3 memory-management objective-c string-literals nsstring

  1. NSString *myString = @"Hello";

  2. NSString *myString = [NSString stringWithString:@"Hello"];

我知道使用方法(1)创建一个指向字符串文字的指针,该字符串文字被定义为静态内存(并且不能被释放),并且使用(2)创建一个将被自动释放的NSString对象.

  • 使用方法(1)不好吗?
  • 有哪些主要区别?
  • 有没有你想要使用的情况(1)?
  • 有性能差异吗?

PS我已经在Stack Overflow上进行了广泛的搜索,虽然对同一主题有疑问,但他们都没有回答我上面发布的问题.

Vla*_*mir 5

正如本答案中所指出的,字符串文字是不可变的字符串对象,并在编译时获取它们的地址 - 因此您不需要在运行时创建相同文字字符串的多个实例.

NSString *myString = @"Hello";
Run Code Online (Sandbox Code Playgroud)

所以这里我们只是将myString分配给指向字符串文字的指针.

NSString *myString = [NSString stringWithString:@"Hello"];
Run Code Online (Sandbox Code Playgroud)

第二行使用便利构造函数创建对象,但是当我们在这里处理不可变对象时,它会产生与字符串文字相同的指针值 - 因此您得到与第一个变量相同的结果(尽管可能执行一些额外的方法调用).

因此,您提到的变体似乎也是如此,但第二个变体也可以执行一些额外的调用.

小样本说明了发生的事情:

NSString* tString = @"lala";
NSString* tString2 = @"lala";   
NSString* tString3 = [NSString stringWithString:@"lala"];
NSString* tString4 = [NSString stringWithFormat:@"%@", @"lala"];

NSLog(@"%p %d", tString, [tString retainCount]);
NSLog(@"%p %d", tString2, [tString2 retainCount]);
NSLog(@"%p %d", tString3, [tString3 retainCount]);
NSLog(@"%p %d", tString4, [tString4 retainCount]);
Run Code Online (Sandbox Code Playgroud)

输出:

 0xd0418 2147483647
 0xd0418 2147483647
 0xd0418 2147483647
 0x50280e0 1
Run Code Online (Sandbox Code Playgroud)