Цель C, Разница между NSSting с «alloc» и без «alloc» - PullRequest
0 голосов
/ 14 марта 2011
 NSString *s1 = @"string1";
 // NSString *s2 = [[NSString alloc]stringWithFormat:@"string2"];
 NSString *s2 = [[NSString alloc] initWithFormat:@"string2"];

Я знаю, что это довольно базовая концепция, но я не уверен на 100%.

Первый не выделяет адрес памяти, а отправляющий выделяет адрес памяти ... Также второй увеличивает счетчик ссылок на переменную, но не первый ... Несмотря на то, что я понимаю концепцию, но не знаю ситуации, когда мне следует использовать первую или вторую ..

Когда я должен использовать первый? также, когда следует использовать для второго?

Заранее спасибо ..

Ответы [ 4 ]

8 голосов
/ 14 марта 2011

Карл прав, но есть некоторая тонкость, о которой нужно помнить. Учтите это:

NSString *s1 = @"string1";
NSString *s2 = [[NSString alloc] initWithString:@"string1"];
NSString *s3 = [NSString stringWithString:@"string1"];
NSString *s4 = [NSString stringWithFormat:@"string1"];

NSLog(@"ptrs %p %p %p %p", s1, s2, s3, s4);

Вывод:

ptrs 0x1000010c0 0x1000010c0 0x1000010c0 0x100108da0

Это верно; s1, s2 и s3 все указывают на один и тот же экземпляр строки, в то время как s4 оказывается новым экземпляром. Это связано с тем, что NSString определяет, когда строка инициализируется из константной строки, и, когда это абсолютно допустимо, возвращает константную строку вместо того, чтобы пытаться выделить новый фрагмент памяти для хранения того же самого объекта. stringWithFormat: случай не так оптимизированы, вероятно, потому, что весь потенциал обработки строк формата делает такой оптимизации и спорный вопрос и, скорее всего, неестественным реализации.

Другими словами, не предполагает, что две строки одинаковы или различны только при проверке кода или при сравнении указателя. Используйте isEqual: или, еще лучше, isEqualToString:.

4 голосов
/ 14 марта 2011

Никогда не используйте второй - +stringWithFormat: - это метод класса. Включая ваш первый пример, у вас есть в основном 3 варианта:

NSString *s1 = @"string1";
NSString *s2 = [[NSString alloc] initWithString:@"string2"];
NSString *s3 = [NSString stringWithFormat:@"string3"];

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

Вы можете сделать s1 или s3 эквивалентным s2, отправив им сообщение retain. Вы также можете превратить s2 в эквивалентный объект, отправив ему сообщение autorelease.

1 голос
/ 14 марта 2011

Не используйте ...WithFormat: метод, если вы просто собираетесь передать ему константную строку. Нет необходимости разбирать строку формата для тривиального случая.

1 голос
/ 14 марта 2011

Строковый литерал, такой как @"string1" (или @"string2" во второй строке), как вы заметили, не является выделением.Строка на самом деле хранится как константа в разделе данных вашего исполняемого файла, как и любая объявленная вами константа.Строки, созданные таким образом, на самом деле не имеют счетчика ссылок;Вы можете отправлять им сообщения -retain и -release, и ничего не произойдет.

Ваша вторая строка неверна;+stringWithFormat: на самом деле является методом класса, и не имеет смысла использовать +stringWithFormat: без каких-либо параметров формата.В общем, просто используйте строковый литерал, если у вас нет особых причин использовать другую форму.Нет необходимости выделять новый объект, если вокруг вашего приложения уже есть постоянный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...