Использование посредника для инициализации объекта - PullRequest
0 голосов
/ 24 июля 2011

Я всегда видел, что мы используем промежуточный объект, например, создаем массив для заполнения другого массива:

characters = [[NSArray alloc] initWithObjects:@"Antony", @"Artemidorus", @"Brutus", nil];  
play.characters = characters;  
[characters release];  

с characters, являющимся NSArray в объекте play.

Я видел то же самое с @property и его self: мы не добавляли новые элементы непосредственно в это свойство, так же как мы напрямую не заполняли characters в примере выше. Это только про "стиль"?

Ответы [ 2 ]

2 голосов
/ 24 июля 2011

Это не вопрос стиля.

play.characters - это свойство, которое может «содержать» существующий массив или nil, но даже если оно «содержит» существующий массив, вы не можете изменить содержимое NSArray, поэтому вы Придется создать новый и присвоить это свойству.

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

1 голос
/ 24 июля 2011

На самом деле в этом маленьком куске кода есть только один массив.

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

Вот что происходит:

Выражение

[[NSArray alloc] initWithObjects:@"Antony", @"Artemidorus", @"Brutus", nil] 

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

Этот вновь созданный объект живет в определенной позиции в памяти, скажем, 0100H. Эта позиция затем сохраняется в переменной characters. В терминах C мы говорим, что characters является указателем на объект.

Тогда свойство @"characters" объекта play устанавливается так, чтобы указывать на ту же позицию в памяти, что и локальная переменная characters. Поэтому теперь есть две переменные (одна из которых также является свойством), которые указывают на один и тот же объект или, если вы предпочитаете, на одну и ту же позицию в памяти. Если свойство имеет тип retain, это автоматически увеличивает счетчик сохранения объекта, поэтому теперь оно равно 2.

С сообщением о выпуске в последней строке объект уменьшает свое количество сохранений на единицу, поэтому в конце этого фрагмента кода на объект указывает свойство play.characters, и он имеет счет сохранения один .

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

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

Если вы хотите сделать все это в одной строке, вы можете написать что-то вроде этого:

play.characters = [[[NSArray alloc] initWithObjects:@"Antony", @"Artemidorus", @"Brutus", nil] autorelease];

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

Это длинное описание, но я надеюсь, что оно проливает некоторый свет на происходящее.

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