iPhone - dealloc - релиз против ноля - PullRequest
24 голосов
/ 22 сентября 2009

Интересно, если кто-то с опытом может объяснить это немного больше. Я видел примеры ...

  [view release];

  view = nil;  

.... внутри (пустой) сделки.

В чем разница и один лучше другого? Какой самый лучший способ?

Когда я проводил тестирование retainCount, я лично видел, как ноль сбрасывал счет от 3 до 0 для меня, но релиз сбрасывает только с 3 до 2.

Ответы [ 5 ]

36 голосов
/ 22 сентября 2009

То, что вы видели, вероятно, это:

1) [foo release];
2) self.bar = nil;
3) baz = nil;
  1. Выпускает объект, обращаясь к нему через переменную экземпляра foo. Переменная экземпляра станет висящим указателем. Это предпочтительный метод в dealloc.

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

  3. Перезапишет указатель baz, ссылающийся на объект с нулем, но не освободит объект. Результатом является утечка памяти. Никогда не делай этого.

8 голосов
/ 22 сентября 2009

Если вы не используете свойства (где self.property = nil также освобождает объект), вы должны ВСЕГДА следовать за выпуском по коду, который устанавливает ссылку на nil, как вы обрисовали в общих чертах:

[view release]; view = nil;

Причина в том, что он исключает возможность использования недопустимой ссылки. Это случается редко и трудно, но может случиться.

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

По сути, это просто хорошая практика, и в какой-то момент она спасет вас от краха, если вы сделаете это привычкой.

2 голосов
/ 03 марта 2010

@ bbullis22 вы заметили, что счетчик остатков упал с 3 до 0, потому что вы установили ссылку на ноль. Затем вы попросили сохранить счет «ноль», который равен нулю. однако объект, на который раньше ссылались, имеет тот же счет сохранения - 1 (из-за установки ссылки на ноль). при использовании release ссылка все еще ссылается на один и тот же объект, поэтому в этой ситуации вы видите снижение количества сохраняемых данных с 3 до 2.

1 голос
/ 22 сентября 2009

Что касается использования внутри вашего кода, в вашем dealloc вам не нужно присваивать свойству свойство, releas ing - это все, что вам нужно сделать.

- (void)dealloc {
    [myProperty release]; // don't need to assign since you won't have the object soon anyway
    [super dealloc];
}
0 голосов
/ 22 сентября 2009

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

При nil вы гарантированно не будете аварийно завершать работу программы, поскольку отправка сообщения на nil ничего не делает.

...