UINavigationController и UIViewController dealloc - PullRequest
3 голосов
/ 12 июля 2010

Я недавно изменил свое приложение для использования UINavigationController, я раньше использовал UINavigationBar с добавлением каскадного subView, что было немного ненадежным.

Я столкнулся с проблемой использования памяти.Инструмент утечки не показывает утечки, но ViewControllers, которые я создаю и добавляю в UINavigationController, никогда не появляются.Таким образом, использование памяти растет с каждым разом, когда я создаю новый VC, а затем нажимаю кнопку возврата NavigationController.

Я просто создаю и добавляю свои VC следующим образом:

DetailViewController* detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
// setups
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];

Приложение никогда не проходит через ViewController dealloc и viewDidUnload методы.Разве они не должны вызываться каждый раз, когда я нажимаю кнопку «Назад»?

Я искал много учебников и прочитал управление памятью Apple, но при использовании NavigationController ничего не говорится о времени жизни ВК в памяти.

Ответы [ 2 ]

5 голосов
/ 13 июля 2010

Может быть, вы не делаете что-то не так, и вместо этого вы сталкиваетесь с чем-то вроде это

В сообщении в блоге был вопрос, должны ли мы вручную выпускать IBOutlets или нет. Как оказалось, мы должны. Это было воспроизводимо в iOS 3.1.3, но я еще не тестировал его в iOS 4.0.

Вторым подходом является переопределение метода сохранения и освобождения контроллеров представления и распечатка счетчика хранения. У меня была проблема с simimlar, что некоторые методы dealloc контроллеров представления не вызывались, поэтому я переопределяю эти методы, чтобы увидеть, остается ли кто-то еще в памяти. Оказывается, это так.

Edit:
Когда я печатал свой счет удержания, он иногда достигал ~ 98, вызванных фреймворком, так что на самом деле не о чем беспокоиться.

Если ваш последний счет удержания остается на 2, и метод dealloc не будет вызван, то есть кто-то, у кого еще есть удержание.

В этом случае вам следует искать в других местах.

Например, другая проблема, с которой я столкнулся во время этой же проблемы: Иногда я бы использовал

[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateUI) userInfo:nil repeats:YES]

для постоянного обновления интерфейса. Но я забыл, что NSTimer сохранит объект target (которым был ViewController). Поскольку NSTimer сохранил ваш контроллер представления, ваш dealloc никогда не будет вызываться, потому что кто-то (NSTimer) все еще сохраняет его. Поэтому вы должны сделать недействительным метод NSTimer BEFORE dealloc, чтобы правильно освободить контроллер представления.

Edit2 в ответ на комментарий ниже:
Сохранение объявленного свойства выполняется следующим образом (пример):

- (void)setTarget:(id)value {
  if (value != target) { 
    [target release];
    target = [value retain];
}

Таким образом, он сначала освобождает ваш текущий self.target, а затем сохраняет новое значение. Так как вы назначаете ноль, ваша цель будет равна нулю впоследствии. Дополнительную информацию о свойствах можно найти в документе Apple.

2 голосов
/ 12 июля 2010

Я тоже это видел. Как вы указали, я не видел ничего определенного в документах, но я считаю, что они сохраняются в памяти до тех пор, пока она не понадобится. Это имеет смысл с точки зрения производительности, поскольку это позволяет приложению быстро перемещаться между различными представлениями.

Суть в том, что я бы не волновался об этом. Вы можете запустить несколько предупреждений о недостаточном объеме памяти в симуляторе и посмотреть, действительно ли он выпускает ваши венчурные капиталисты.

...