应该将 viewDidUnload 中的哪些工作移至 didReceiveMemoryWarning?
Posted
技术标签:
【中文标题】应该将 viewDidUnload 中的哪些工作移至 didReceiveMemoryWarning?【英文标题】:What works in viewDidUnload should be moved to didReceiveMemoryWarning? 【发布时间】:2012-10-03 12:27:00 【问题描述】:在新的 ios 6 中,viewDidUnload
已被弃用,我们被指示改用didReceiveMemoryWarning
来管理 UIViewController 实例和子类中的对象。在didReceiveMemoryWarning
中将 nil 分配给 UIView 种类是否同样有效,就像在 viewDidUnload
中所做的那样?
我问这个是因为这两种方法的工作方式似乎不同。似乎 didReceiveMemoryWarning
不能保证再次调用 viewDidLoad
以重新实例化任何必要的 UIView。
我怀疑在 iOS 6 中,无需手动释放 UIView 即可完成内存管理。请帮助我了解我在理解 UIViewController 的生命周期时遗漏了什么。
【问题讨论】:
【参考方案1】:我现在首选的方法如下:
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
if (self.isViewLoaded && !self.view.window)
self.view = nil;
// Do additional cleanup if necessary
请注意,测试 self.isViewLoaded
是必不可少的,否则访问视图会导致它加载 - 甚至 WWDC 视频也往往会错过。
如果您对子视图的其他引用是弱引用,则不必在此处将它们设为 nil,否则您也想将它们设置为 nil。
您应该完全摆脱viewDidUnload
,并且那里的每个代码都应该移动到适当的位置。无论如何,它不能保证在 iOS 6 之前被调用。
【讨论】:
另外,如果这是一件重要的事情,你不认为基础实现会这样做吗? 你说得对,这不是必需的。对于基于图像的视图的草率实现,内存量可以从几个字节到几十兆字节变化很大。所以我们可以很容易地释放它,但我们不必这样做。尤其是对于很多控制器,它仍然可能是一个好主意,而且占用空间越小,应用程序就越有可能不会在后台被杀死。因此,我的建议是更多地取消它除非您确定保留它很便宜。当然,设置成本也需要考虑。【参考方案2】:在viewDidUnload:
的 iOS 参考中,它指出这在 iOS 6 中已被弃用,因为
视图不再在内存不足的情况下被清除,所以这 方法永远不会被调用
它没有说明将此代码放在didReceiveMemoryWarning:
中。由于在内存不足的情况下不再清除视图,因此您不必担心在任何一种方法中都会清理视图。
【讨论】:
这是正确答案。从 ios6 开始,消除视图不是您关心的问题。 viewDidLoad 未被弃用,viewDidUnload 被弃用。至于不退出,我建议观看 WWDC 2012 视频,演讲者经常推荐这个。同样,这不是必须的,但他们清楚地声明要在此处释放尽可能多的内存(包括视图)。文档说不再调用该方法,因为人们滥用此方法进行其他清理并经常依赖它。所以不,这个答案是不正确的。这是相当错误的。苹果刚刚给了程序员更多的控制权。 “在内存不足的情况下不再清除视图”意味着您肯定必须担心清理didReceiveMemoryWarning:
中的视图?否则不会释放视图,也不会减少内存使用量。
当然,我可能误解了文档的含义。 Joe Conway's blog on this topic 解释了如何 iOS 6 重新获得didReceiveMemoryWarning
的内存,以及为什么视图本身不再被清除。
@adamjansch 如果我的赏金引起了人们对这个问题的关注,那么提供赏金是正确的决定。我的想法和你的完全一样,我仍然很难相信没有必要再打电话给viewDidUnload
。感谢您的博文。【参考方案3】:
Eiko 的回答不正确,当收到内存不足警告时,我们不应该将self.view
设置为nil
。这样做是没有用的,而且可能有害。
iOS 6 会自动释放当前未显示的视图位图,详情请参阅http://thejoeconwayblog.wordpress.com/2012/10/04/view-controller-lifecycle-in-ios-6/。
【讨论】:
以上是关于应该将 viewDidUnload 中的哪些工作移至 didReceiveMemoryWarning?的主要内容,如果未能解决你的问题,请参考以下文章
没有为 UIscrollView 中的 viewControllers 调用 ViewDidUnload
NSNotification、addObserver 和 removeObserver - ViewDidUnload 和 dealloc 中的 removeObserver?