Освобождение объекта в Objective-C: Зачем освобождать объект дважды в методах viewDidUnload и dealloc? - PullRequest
1 голос
/ 02 сентября 2011

У меня есть вопрос об освобождении объекта в 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];}

Спасибо,Sam

Ответы [ 3 ]

3 голосов
/ 02 сентября 2011

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

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

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

0 голосов
/ 02 сентября 2011

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

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

0 голосов
/ 02 сентября 2011

Для оптимизации доступной памяти рекомендуется реализовать ленивые методы получения (фактически ленивые инициализаторы) в 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 , но позже

...