Освобождение объекта в Objective-C: Зачем освобождать объект дважды в методах viewDidUnload и dealloc?


У меня есть вопрос об освобождении объекта в target-c. Некоторые примеры кодов я видел в главе 9 "Начало разработки для iphone 4"(стр. 287). Пример кода освобождает объект дважды: как в viewDidUnload, так и в методе dealloc. Вот примеры кодов:

- (void)viewDidUnload {
self.list = nil;
[childController release], childController = nil;}

- (void)dealloc {
[list release];
[childController release];
[super dealloc];}

childController объявлен как экземпляр подкласса UIViewController. Почему он выпускается как в методе viewDidUnload, так и в методе dealloc? Поскольку childController уже выпущен в viewDidUnload, необходимо ли снова его выпускать в методе dealloc? Основываясь на моем понимании, я напишу код вроде:

- (void)viewDidUnload {
self.list = nil;
childController = nil;}
- (void)dealloc {
[list release];
[childController release];
[super dealloc];}

Спасибо,
Сэм

3 ответа

Проблема в viewDidUnload не гарантированно будет вызываться каждый раз, как dealloc метод. (проверьте этот вопрос).

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

А также призывая выпустить на nil не вызовет никаких проблем, поэтому безопасно вызывать release для сохраненных объектов в вашем dealloc метод, предполагающий, что указатели установлены в ноль после того, как были выпущены в другом месте (как в viewDidUnload в твоем примере).

Я немного исследовал, потому что я не был уверен. И все, что вам нужно знать, это здесь: Когда я должен выпускать объекты в -(void)viewDidUnload, а не в -dealloc?

По сути, в viewDidUnload вы освобождаете объекты, созданные в начале жизненного цикла представления (loadView, viewDid load и т. Д.). Поэтому, если ваш viewController получает предупреждение о памяти, он выгружает представление и снова загружает его, а затем ваши объекты будут освобождены в viewDidUnload и снова инициализированы в loadView/viewDidLoad/ect

Для оптимизации доступной памяти рекомендуется реализовать ленивые геттеры (фактически ленивые инициализаторы) в UIViewControllers и выпускать легко перераспределяемые объекты в viewDidUnload. (Упрощенный) ленивый получатель что-то вроде:

- (UIView *)footerView {
    if (_footerView) {
        return _footerView;
    }
    UIView *view = [[UIView alloc] initWithFrame:A_FRAME];
    return (_footerView = view);
}

Итак, в viewDidUnload я выпущу _footerView, потому что я могу получить его позже без усилий. Выпуск _footerView в методе dealloc не является ошибкой, потому что: 1) в цели c можно отправлять сообщения объектам nil, 2) dealloc не будет выполняться одновременно с viewDidUnload, но позже

Другие вопросы по тегам