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

时间:2010-06-16 10:36:49

标签: objective-c memory-management nsstring string-literals

  1. NSString *myString = @"Hello";

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

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

    • 使用方法(1)不好吗?
    • 有哪些主要区别?
    • 您是否有任何想要使用的情况(1)?
    • 是否存在性能差异?

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

1 个答案:

答案 0 :(得分:5)

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

NSString *myString = @"Hello";

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

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

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

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

说明发生了什么的小样本:

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]);

输出:

 0xd0418 2147483647
 0xd0418 2147483647
 0xd0418 2147483647
 0x50280e0 1