В чем разница между этими двумя способами создания строк NSStrings? - PullRequest
3 голосов
/ 16 июня 2010
  1. NSString *myString = @"Hello";

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

Я понимаю, что использование метода (1) создает указатель на строковый литерал, который определяется как статическая память (и не может быть освобожден), а использование (2) создает объект NSString, который будет автоматически освобожден.

  • Плохо ли использовать метод (1)?
  • Каковы основные различия?
  • Есть ли случаи, когда вы хотели бы использовать (1)?
  • Есть ли разница в производительности?

P.S. Я много раз искал в переполнении стека, и хотя есть вопросы по той же теме, ни у одного из них нет ответов на вопросы, которые я опубликовал выше.

1 Ответ

5 голосов
/ 16 июня 2010

Как указано в этот ответ строковые литералы являются неизменяемыми строковыми объектами и получают их адрес во время компиляции - поэтому вам не нужно создавать несколько экземпляров одной и той же строки литерала во время выполнения.

NSString *myString = @"Hello";

Итак, мы просто назначаем myString указателю на строковый литерал.

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

Вторая строка создает объект с помощью удобного конструктора, но поскольку мы имеем здесь дело с неизменяемыми объектами, это приводит к тому же значению указателя на строковый литерал - так вы получите тот же результат, что и в первом варианте (хотя, возможно, выполняет некоторые дополнительные вызовы методов).

Так что, кажется, что упомянутые вами варианты делают то же самое, но 2-й также может выполнять некоторые дополнительные вызовы.

Небольшой пример, иллюстрирующий, что происходит:

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
...