Почему мой вид UIViewController выгружается, когда он виден?

Эта проблема никогда не случалась со мной. У меня есть UIViewController внутри UINavigationController. Когда получено предупреждение о памяти (неважно уровень), вызывается метод viewDidUnload контроллера visible, поэтому представление выгружается, и я получаю потрясающий черный экран (с панелью навигации вверху) .

Я тестирую iPad 1 на iOS 4.3.3.

Какие-либо предложения?


person emenegro    schedule 02.08.2012    source источник
comment
Как выглядит свойство views навигационного контроллера, когда вы получаете это предупреждение (т.е. что в нем, порядок и т. д.)? Кроме того, в вашем viewDidUnload добавьте журнал NSLog(@WINDOW: %@, self.view.window) - это скажет вам, действительно ли это представление видимо.   -  person David H    schedule 22.08.2012
comment
Это реальное предупреждение или вы смоделировали?   -  person David H    schedule 25.08.2012
comment
Дэвид, это настоящий.   -  person emenegro    schedule 26.08.2012
comment
вы звоните [super viewDidUnload]; ?   -  person Michal Zaborowski    schedule 27.08.2012
comment
только на вашем дочернем контроллере просмотра, а не на навигационном контроллере?   -  person nielsbot    schedule 28.08.2012
comment
Да, выгруженный вид содержится в навигационном контроллере.   -  person emenegro    schedule 29.08.2012
comment
Действительна ли ваша иерархия контроллеров просмотра? Как все ваши контроллеры были добавлены в корень?   -  person Resh32    schedule 29.08.2012


Ответы (3)


Насколько я понимаю, метод viewDidUnload вызывается функцией didRecieveMemoryWarning в UIViewController (суперклассе). В основном iOS выдает вам пару предупреждений и ожидает, что использование вашей памяти снизится. Если вы продолжите игнорировать их, ОС убьет ваше приложение.

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

Или, что еще лучше, проверьте, является ли self текущим представлением в self.navigationController.visibleViewController, и если да, не передавайте вызов предупреждения о памяти в [super didRecieveMemoryWarning].

Если вы держите кэши изображений или что-то в этом роде, просто очистите их.

ХТН

person dineth    schedule 29.08.2012
comment
Небольшое замечание: iOS6 изменила это поведение. UIViewController больше не вызывает автоматически viewDidUnload при предупреждении о памяти по умолчанию. Он просто вызывает метод didReceiveMemoryWarning и все. Только iOS6. - person dineth; 18.10.2012

В соответствии с рекомендациями по управлению памятью Apple, когда viewcontroller получает предупреждения о памяти в критических ситуациях, он напрямую вызывает viewDidUnload, чтобы можно было управлять памятью, освобождая представление.

На самом деле ios дает возможность очистить ваши временные данные, которые будут полезны при воссоздании представления. Поскольку ваш UIViewCotroller является корнем viewcontroller navigationcontroller, вы видите oly панель навигации, представление выгружается.

person kaar3k    schedule 27.08.2012
comment
@emenegro См. это ссылка, раздел «Понимание того, как представления загружаются и выгружаются» жирным шрифтом На рис. 4-2 жирным шрифтом показано, как представления выгружаются, когда ViewController получает предупреждение о памяти. Также его объяснение над рисунком. - person kaar3k; 28.08.2012
comment
Я видел эти документы некоторое время назад, и я нигде не вижу, что является исключительной ситуацией, в которой видимое представление может быть выгружено. Эти документы объясняют, как представление выгружается, и C&P из этапов цикла выгрузки: если представление не может быть безопасно выпущено (например, оно видно на экране).... Итак, я хочу знать, возможно ли выгрузить представление будучи видимым, в данном случае находясь внутри стека навигации. - person emenegro; 28.08.2012

Вы получаете viewDidUnload в случае нехватки памяти на контроллерах, когда iOS определила, что представления больше не нужны. Помните, что Apple внесла некоторые улучшения в реализации в более поздних версиях iOS, поэтому может быть хуже видно, что происходит в 5.x. Во-вторых, вы должны просмотреть иерархию контроллера представления.

person Bernd Rabe    schedule 28.08.2012