Установите nil для дочерних контроллеров представления в viewDidUnload

Мое приложение для iOS основано на навигации со следующей структурой:

@interface ViewControllerA : UIViewController
@property (strong,nonatomic) ViewControllerB *viewControllerB;
@property (strong,nonatomic) ViewControllerC *viewControllerC;
...

viewControllerB и viewControllerC создаются до того, как navigationController ViewControllerA подтолкнет их.

Насколько я понимаю, все, что сохраняется в ViewControllerA, должно быть установлено на ноль в ViewControllerA viewDidUnload. Должен ли я сделать то же самое с дочерними контроллерами представления? Нравится:

-(void)viewDidUnload
{
    self.viewControllerB=nil;
    self.viewControllerC=nil;
}

Я обнаружил проблему, когда от viewControllerC инициировалось «предупреждение о полученной памяти». После этого был вызван viewDidUnload родительского контроллера представления (т.е. viewControllerA), тем самым установив nil в 'viewControllerB'. Неожиданно также вызывается viewDidUnload из viewControllerB. Итак, я получил «сообщение, отправленное освобожденному объекту», если я установил nil для подвидов viewControllerBviewControllerB viewDidUnload).

Означает ли это, что я не должен устанавливать nil для дочерних контроллеров представления? Как лучше всего управлять памятью в этой ситуации?

P.S. Я использую АРК.


person Nimit Pattanasri    schedule 02.06.2012    source источник


Ответы (1)


После вызова viewDidUnload UIViewController должен сохранять свое состояние, то есть не выпускать ничего, что нельзя легко воссоздать. Обычно вы обнуляете любые данные, связанные с иерархией представлений, например сильные ссылки на некоторые подпредставления или пользовательские данные, созданные в файле viewDidLoad. В вашем примере ожидается, что ваш родительский контроллер A сможет восстановиться после вызова viewDidUnload, а это означает, что в будущем вызов viewDidLoad восстановит ваш контроллер, а не сбой.

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

Но поскольку вы должны поддерживать состояние своих контроллеров после viewDidUnload, вы не должны устанавливать для своих дочерних контроллеров значение nil. Что вы должны сделать, так это отказаться от всех сильных ссылок, которые у вас есть в подвидах контроллера (например, строгая ссылка на UILabel и т. д.), но не отказываться от самого контроллера.

person Emmanuel Sys    schedule 02.06.2012