Освобождение объекта в 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, но позже