Выпустить в viewDidUnload и dealloc как?
Я был в предположении, что viewDidUnload
всегда вызывается, когда контроллер освобождается. Правильное ли это предположение?
Я только что изучил некоторые странные вещи и установил точку останова в контроллере viewDidUnload
и dealloc
. Похоже, что вызывается dealloc
, но метод viewDidUnload
никогда не вызывается. Я даже добавил self.view = nil
к моему dealloc
, и он все еще не называл его.
Означает ли это, что сохраненные объекты представлений, которые я выпустил в методе viewDidUnload
, также должны быть выпущены в моем методе dealloc
, чтобы убедиться, что они действительно исчезли?
Я знаю, что в StackOverflow есть много других вопросов о viewDidUnload
, но никто конкретно не рассматривает эту проблему о дублировании высказываний релиза между двумя методами.
Более конкретный пример в новом проекте 3.1.2 SDK:
@implementation TestViewController
@synthesize label;
- (IBAction)push {
TestViewController *controller = [[[TestViewController alloc] initWithNibName:@"TestViewController" bundle:nil] autorelease];
[self.navigationController pushViewController:controller animated:YES];
}
- (void)viewDidUnload {
self.label = nil;
NSLog(@"viewDidUnload was called");
}
- (void)dealloc {
[super dealloc];
NSLog(@"label retain count: %i", [label retainCount]);
}
@end
Мой делегат приложения создает простой контроллер навигации с одним из них в качестве его корневого контроллера. Когда я нажимаю кнопку, связанную с push
3 раза, а затем три раза нажимаю кнопку "Назад", создается следующий вывод.
ViewDidUnloadTest[2887:207] label retain count: 2
ViewDidUnloadTest[2887:207] label retain count: 2
ViewDidUnloadTest[2887:207] label retain count: 2
Что выше 2, я бы подумал, что это будет. Один раз удерживается один раз, а контроллер - один раз. Но после dealloc
я ожидал, что вид исчезнет, выпустив мой ярлык, и контроллер не будет вызывать viewDidUnload
и освободить его. Хотя в этой точке может быть autorelease
, отбрасывающий счетчик.
Но по крайней мере ясно, что viewDidUnload
вообще не вызван, что противоречит этому ответу: Всегда ли вызываются viewDidUnload и dealloc при срыве UIViewController?
Возможно, мне нужно просто вызвать [self viewDidUnload]
во всех моих методах dealloc на контроллерах? Хуже, чем может случиться, что я установил свойство в nil дважды, верно?
Ответы
Ответ 1
Если вам не нужно прерывать цикл удержания, вы должны просто освобождать объекты только в методе dealloc
. viewDidUnload
является исключением; он вызывается в ситуациях с низкой памятью и должен использоваться для выпуска всего, что вы можете.
Если вам нужно освободить их в другом месте, тогда всегда устанавливайте ссылку на nil после release
. Это защитит ваше приложение от взорвания позже (вероятно, в dealloc
).
Обратите внимание, что в документации явно указано, что свойство view уже будет равно нулю при вызове viewDidUnload
.