Нужно ли выпускать ивар и одновременно устанавливать синтезированный ивар на ноль? - PullRequest
9 голосов
/ 17 июня 2009

Я видел код (возможно, собственный пример кода Apple), написанный таким образом, что он освобождает ivar в dealloc и устанавливает свойство в viewDidUnload.

, например

- (void)viewDidUnload
{
  self.navigationController = nil;
}

- (void)dealloc
{
   [_navigationController release];
}

Почему они в двух местах? Кроме того, зачем устанавливать ноль в одном и выпускать в другом. Кажется, что self.property = nil просто позаботится обо всем, так как он освободит и установит ivar в nil.

Ответы [ 3 ]

5 голосов
/ 17 июня 2009

Вы правы: вы действительно можете сделать self.property = nil везде, включая dealloc. Единственным недостатком является то, что если метод setter делает что-то более сложное, чем просто освобождение ivar, вы можете попытаться получить доступ к другим уже освобожденным полям и т. Д.

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

1 голос
/ 17 июня 2009

Apple рекомендует не вызывать сеттеры в процедурах init и, особенно, в dealloc.

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

Следовательно, вы обычно используете:

_navigationController = [[NavController alloc] init];

код стиля в вашей процедуре инициализации,

[_navigationController release];
Код стиля

в вашем dealloc и сеттеры в другом коде, где, как известно, объект полностью завершен.

Некоторые случаи для рассмотрения:

  • Подкласс переопределяет setNavigationController и ссылается на свои собственные ivars, выделенные init. Сбой при инициализации.
  • Подкласс переопределяет setNavigationController и ссылается на свои собственные ivars, выпущенные в dealloc. Сбой при ударе.
  • Подкласс переопределяет setNavigationController и перерисовывает некоторые части экрана. Бессмысленная трата циклов или глючный дисплей.
  • Другие объекты, освобождаемые одновременно, наблюдают за навигационным контроллером, и эти наблюдатели срабатывают во время освобождения
  • и т.д.
0 голосов
/ 17 июня 2009

Если вы полагаетесь на сборку мусора (доступно в Objective-C 2.0), тогда установка ivar на nil и вызов release достигнут того же конца.

Я предполагаю, что код, который вы просматриваете, управляет памятью с помощью release и устанавливает его только на nil, чтобы впоследствии вы не пытались получить доступ к объекту, которого больше нет. nil - это больше бухгалтерия, чем управление памятью, когда вы не полагаетесь на ГХ.

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