为什么我的UIViewController的视图在可见时被卸载?

6
这个问题从未发生在我身上。我在 UINavigationController 中有一个 UIViewController。当收到内存警告(无论级别如何)时,会调用可见控制器的 viewDidUnload 方法,因此视图被卸载,我得到了一个带有导航栏的惊人黑屏。
我正在使用 iOS 4.3.3 上的 iPad 1 进行测试。
有什么建议吗?

1
当您收到此警告时,导航控制器的“views”属性是什么样子(即其中包含什么,顺序等)?另外,在您的viewDidUnload中,添加日志NSLog(@“WINDOW:%@”,self.view.window)-这将告诉您该视图是否可见。 - David H
大卫,这是真的。 - emenegro
你在调用 [super viewDidUnload]; 吗? - Michal Zaborowski
仅限于您的子视图控制器,而不是导航控制器? - nielsbot
是的,未加载的视图包含在导航控制器中。 - emenegro
显示剩余2条评论
3个回答

1
据我所知,viewDidUnload方法是由UIViewController(超类)中的didRecieveMemoryWarning函数调用的。基本上,iOS会给你一些警告,并期望看到你的内存使用量下降。如果你继续忽略这些警告,操作系统将会杀死你的应用程序。
有时候,保持一些视图的运行是至关重要的,所以我解决这个问题的方法是简单地覆盖didRecieveMemoryWarning方法,在其中不做任何事情。
或者更好的方法是检查self是否是self.navigationController.visibleViewController中的当前视图,如果是,则不将内存警告调用传递给[super didRecieveMemoryWarning]
如果你正在保存图像缓存或其他东西,只需清空它们即可。
希望对你有所帮助。

快速提醒,iOS6现在已经改变了这个行为。UIViewController不再默认自动调用viewDidUnload方法来处理内存警告。它只会调用didReceiveMemoryWarning方法,就这样而已。仅适用于iOS6。 - dineth

0
根据苹果的内存管理指南,当一个视图控制器在关键情况下接收到内存警告时,它会直接调用viewDidUnload以便通过释放视图来管理内存。
实际上,iOS提供了清除临时数据的机会,这在重新创建视图时非常有用。由于您的UIViewCotrollernavigationcontroller的根viewcontroller,因此只有导航栏被卸载,而视图则被卸载。

@emenegro 请查看此链接,第'Understanding How Views Are Loaded and Unloaded'章节。粗体图4-2 粗体展示了当ViewController接收到内存警告时如何卸载视图,上图下方有详细解释。 - kaar3k
我以前看过这些文档,但没有找到任何关于可见视图在什么异常情况下会被卸载的说明。那些文档解释了视图如何被卸载,并从卸载周期的步骤中复制和粘贴了一段话:“如果视图无法安全释放(例如,它在屏幕上可见)…”。所以我想知道在导航堆栈中,是否有可能在可见的情况下使一个视图被卸载。 - emenegro

0

在控制器中,当iOS确定视图不再需要时,您会在低内存情况下收到viewDidUnload。请记住,苹果在后续版本的iOS上对实现进行了一些改进,因此最好看看在5.x下会发生什么。其次,您应该检查您的视图控制器层次结构。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接