Почему люди всегда используют переназначение для переменных экземпляра в Objective-C (а именно iPhone)?

Я всегда вижу пример кода, где в методе viewDidLoad вместо того, чтобы говорить, например

someInstanceVar = [[Classname alloc] init];

они всегда идут

Classname *tempVar = [[Classname alloc] init];
someInstanceVar = tempVar;
[tempVar release];

Почему это? Разве это не то же самое, просто дольше?

Ответ 1

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

Детали:

Ваш второй пример создаст зомби, так как осталось var, удерживая указатель на память, которая была выпущена. Более вероятный пример использования выглядит следующим образом:

tempVar = [[Classname alloc] init];
self.propertyVar = tempVar;
[tempVar release];

Предполагая, что propertyVar объявлен как свойство copy или retain, этот код отдает право собственности на новый объект классу.

Обновление 1: Следующий код эквивалентен, но не рекомендуется * в iOS, поэтому, вероятно, большинство программ для iPhone используют первый шаблон.

self.propertyVar = [[[Classname alloc] init] autorelease];

* autorelease обескуражен в iOS, потому что это может вызвать проблемы при злоупотреблении. Самый простой способ убедиться, что вы никогда не злоупотребляете этим, - никогда не использовать все это, поэтому вы часто будете видеть код iOS, который использует alloc/init и release, даже если autorelease будет приемлемым. Это вопрос предпочтения кодера.

Обновление 2: Этот шаблон выглядит запутанным сначала из-за управления памятью, который Cocoa выполняет автоматически за кулисами. Ключом к этому является точечная нотация, используемая для установки переменной-члена. Чтобы проиллюстрировать это, учтите, что следующие две строки кода идентичны:

self.propertyVar = value;
[self setPropertyVar:value];

При использовании точечной нотации Cocoa вызывается свойство accessor для указанной переменной-члена. Если это свойство было определено как свойство copy или retain (и это единственный способ работы этого шаблона без создания зомби), произойдет несколько очень важных вещей:

  • Все значения, ранее сохраненные в propertyVar, были выпущены
  • Новое значение сохраняется или копируется
  • Любые побочные эффекты (например, уведомления KVC/KVO) автоматически обрабатываются