Простой шаблон для высвобождения свойств - PullRequest
1 голос
/ 20 августа 2011

У меня есть общий вопрос относительно управления памятью свойств. В настоящее время я всегда использую свойства без явного объявления связанных ivars. И для каждого сохраненного или скопированного свойства я освобождаю его счетчик сохранения как в методах dealloc, так и в viewDidUnload:

-(void)dealloc{
  [self.myProperty release];
  [self.myOutlet release];
  [super dealloc];
}

- (void)viewDidUnload{
  [super viewDidUnload];
  self.myProperty = nil;
  self.myOutlet = nil;
}

Теперь я знаю, что только выходы и свойства, сохраненные в главном представлении, должны быть установлены в nil в viewDidUnload, а остальные свойства должны быть освобождены в dealloc. Но эй, почему я должен беспокоиться о каждом свойстве, где оно должно быть освобождено - в dealloc или в viewDidUnload? Если какое-либо свойство будет освобождено дважды, это нормально, потому что оно не приведет к сбою приложения, отправив сообщение объекту nil. Размещение релиза в обоих местах (dealloc и unload) экономит время и предотвращает возникновение ошибок позже при выполнении рефакторинга кода и забывчивости менять место выпуска. Есть критики и крики на это? :)

Ответы [ 2 ]

1 голос
/ 20 августа 2011

Мой предыдущий ответ по этому вопросу обсуждает, что Apple рекомендует и почему.Соответствующие части воспроизведены здесь для ясности:

Кроме того, из Apple Docs на -viewDidUnload:

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

Итак, поехали.Если у вашей торговой точки есть свойство, связанное с ней (что все они должны больше), то обнулите его в -viewDidUnload - но не отпускайте его.Это имеет смысл, если учесть, что на самом деле происходит в синтезированном методе доступа;код выглядит примерно так:

- (void) setMyView1 : (UIView *) view {
   if (myView1) // the associated IVAR is already set
      [myView1 release];

   myView1 = [view retain];
}

Как видите, установка свойства синтеза на nil неявно освобождает сохраненный объект.

Также из документов по -dealloc:

Если вы реализуете этот метод, но создаете свое приложение для iOS 2.x, ваш метод dealloc должен освободить каждый объект, но также должен установить ссылку на этот объект на nil перед вызовом super.

Если вы не поддерживаете iOS2.x, нет необходимости устанавливать нулевые объекты в dealloc.

Итак, для суммирования документов Apple по -viewDidUnload и -dealloc:

  • В -viewDidUnload нулевые свойства (включая свойства IBOutlet), но не освобождают их
  • В -dealloc свойства выпуска,но не ноль их (если не строить для 2.x).
1 голос
/ 20 августа 2011

Если вы используете средства доступа к свойству в -dealloc, поскольку у вас нет прямого доступа к ivar, вам следует сделать то же самое в -dealloc, что и в -viewDidUnload:

self.myProperty = nil;

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

Разница между -dealloc и -viewDidUnload заключается в том, что вы все еще работаете с полным, полностью функциональным объектом в -viewDidUnload, тогда как объект может быть частично освобожден в -dealloc.

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