Вопрос: Выпустить в 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 на контроллерах? Хуже, чем может случиться, это то, что я дважды установил свойство, равное нулю, верно?


14


источник


Ответы:


Если вам не нужно нарушать цикл удержания, вы должны в общем  только освобождение объектов в вашем dealloc метод. viewDidUnload является исключением; он вызывается в ситуациях с низкой памятью и должен использоваться для выпуска всего, что вы можете.

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

Обратите внимание, что в документации явно указано, что свойство view уже будет равно нулю, если viewDidUnload называется.


20