NSString сносит мой разум - PullRequest
2 голосов
/ 18 октября 2011

У меня есть три NSString свойства, объявленные так:

@property(nonatomic,retain) NSString *currentPassword;
@property(nonatomic,retain) NSString *newPassword;
@property(nonatomic,retain) NSString *confirmPassword;

Я инициализирую их методом viewDidLoad:

currentPassword = [[NSString alloc]init];
newPassword = [[NSString alloc]init];
confirmPassword = [[NSString alloc]init];

Самое смешное, что они являются одним и тем же объектом после инициализации их как разные объекты!

enter image description here

Это какая-то оптимизация компилятора?

Спасибо

Ответы [ 4 ]

3 голосов
/ 18 октября 2011

Это какая-то оптимизация компилятора?

Не совсем.Это значение особого случая для константы, и оптимизация общего конкретного неизменяемого типа / значения, которая была реализована классом NSString.

NSString является неизменной.Нет причины, по которой необходимо несколько экземпляров одной и той же пустой строки.В таких простых случаях -[NSString init] может принимать форму:

static NSString* const EmptyNSString = @"";

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

аналогично, + [NSString string]:

+ (id)string
{
  return EmptyNSString;
}

Таким образом, существует несколько статических неизменяемых объектов, которые используются таким образомгде это имеет смысл.Другие очевидные примеры включают + [NSArray array] и + [NSNumber numberWithBool:].

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

Это происходитработать, потому что NSString как кластер классов: Вам возвращается объект одного из многих непрозрачных типов, который реализует интерфейс, объявленный NSString.Следовательно, тип NSMutableString может затем реализовать init надлежащим образом:

- (id)init
{
  self = [super init];
  if (nil != self) { ... }
  return self;
}

Наконец, почти во всех случаях вы должны объявить свои свойства NSString как copy.

2 голосов
/ 18 октября 2011

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

Использование конструктора без параметров может быть одним из примеров.Вы также можете проверить, что +stringWithString:-initWithString:) также возвращают (сохраненную) строку параметра, а метод copy в NSString эквивалентен retain.

Помните, что оптимизация тольковозможно, потому что мы знаем, что экземпляр NSString не изменится, и те же тесты с NSMutableString, скорее всего, будут создавать новые экземпляры строк.

PS Об использовании NSAssert:

NSAssert Создает утверждение, если данное условие ложно.

Таким образом, ваше условие утверждения должно быть изменено:

NSAssert(currentPassword && newPassword && confirmPassword,@"nil field");
0 голосов
/ 18 октября 2011

NSString определяется как неизменяемый тип, поэтому всякий раз, когда компилятор может оптимизировать вещи, комбинируя идентичные строки, он должен. если вы используете @"myString" в двух отдельных местах вашего кода, они будут ссылаться на один и тот же объект. @"" строки имеют класс NSConstantString

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

Если у вас есть NSString в качестве свойства, вы должны указать атрибут «copy».

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