Разница между этими двумя методами NSString - PullRequest
7 голосов
/ 26 октября 2011

Так что меня только что спросили об этом сегодня на собеседовании, и после некоторого поиска в Google все еще не может найти ответ (фактически я даже не мог найти никакого кода вообще, который использовал бы метод [NSString string]).

В чем разница между

  1. NSString *someString = [NSString string];
  2. NSString *someString = [[NSString alloc] init];

Теперь мои первоначальные мысли были о том, что [NSString string] вернетсяобъект, который будет автоматически освобожден, тогда как использование alloc и init вернет объект, который был сохранен.Однако кажется, что этот ответ был неправильным.

Я посмотрел ссылку на класс NSString в документах Apple, но все, что он говорит, это

Returns an empty string.

+ (id)string 

Return Value
An empty string.

Может ли кто-нибудь объяснить мне, что именноРазница между этими двумя есть?

Ответы [ 5 ]

5 голосов
/ 26 октября 2011

Это был ваш ответ, и вы спросили , почему ваш ответ был неверным? Я спрашиваю, потому что ваше предположение в основном верно (на более высоком уровне).

Он не совсем «сохраняется» при возврате из alloc+init, это объект, к которому вы имеете одну ссылку, и должен балансировать с release или autorelease. Для вспомогательного конструктора (+[NSString string]) вам возвращается объект, на который у вас нет нулевых ссылок, но который вы можете ожидать до тех пор, пока текущий пул автоматического выпуска не будет извлечен, если вы не отправите ему явное сохранение (при условии, что MRC или ARC так как он помечен iOS).

На более низком уровне вы могли бы сделать некоторые предположения, но я не ожидал бы, что этот вопрос будет во многих интервью по предмету (если вы не сказали им, что вы среднего или старшего уровня). По сути, это определяется реализацией, но обе формы могут возвращать одну и ту же статическую константу NSString (это могло быть тем, что искал интервьюер). Для иллюстрации:

@implementation NSString

static NSString * const EmptyNSString = @"";

- (id)init
{
    self = [super init];
    [self release];
    return EmptyNSString;
}

+ (id)string
{
    return EmptyNSString;
}

...

Опять же, это определенная реализация, но очевидная оптимизация. Кроме того, эта оптимизация делает физически подклассы конкретных неизменяемых типов (NSString) трудными для изменяемых вариантов (NSMutableString) , в некоторых случаях .

4 голосов
/ 26 октября 2011

Правильный ответ таков:

NSString *someString = [NSString string];

дает вам пустую строку, которой вы не владеете и которую не должны освобождать (согласно правилам управления памятью)

, тогда как

NSString *someString = [[NSString alloc] init];

дает вам пустую строку, которой вы владеете и которую вы должны освободить (согласно правилам управления памятью).

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

На самом деле, вы, вероятно, получите (в обоих случаях) один и тот же указатель на константный объект некоторого подкласса NSString, вероятно, со счетом сохранения UINT_MAX, который используется во время выполнения как флаг для отключения нормальное сохранение поведения релиза для константных строк. На самом деле я не пробовал вышеизложенное, потому что никто, кроме разработчиков SDK Objective-C, не нуждается в этом.

4 голосов
/ 26 октября 2011

Теперь мои первые мысли были о том, что [NSString string] вернет объект, который будет автоматически освобожден

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

тогда как использование alloc и init вернет объект, который был сохранен

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

0 голосов
/ 26 октября 2011

Единственное, что я могу себе представить, это:

  1. Не выделяет память, поскольку она не создана с помощью alloc. Это константа (пустая строка), созданная системой, и ее не нужно освобождать.

  2. Вы выделяете память для строки NSS самостоятельно, что означает, что вы должны отслеживать, все еще «живет» строка NSString или нет, когда вам это нужно, и, следовательно, необходимо освободить ее.

0 голосов
/ 26 октября 2011

Вы не часто видите

NSString *someString = [NSString string]; 

, потому что он такой же, как

NSString *someString = @""; 

, который короче.Обычно используется для создания пустой NSMutableString

NSMutableString* s = [NSMutableString string];
...