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

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

someInstanceVar = [[Classname alloc] init];

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

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

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

1 Ответ

12 голосов
/ 27 сентября 2010

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

Подробности:

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

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

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

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

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

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

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

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

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

  1. Независимо от того, какое значение было ранее сохранено в propertyVar, оно освобождается
  2. Новое значение сохраняется или копируется
  3. Любые побочные эффекты (например, уведомления KVC / KVO) обрабатываются автоматически
...