didReceiveMemoryWarning和viewDidUnload

时间:2010-12-04 15:44:41

标签: iphone memory-management uiview uiviewcontroller

从Apple的View Controller编程指南/有效管理内存;

  

didReceiveMemoryWarning

     

使用此方法取消分配与视图控制器关联的所有非关键自定义数据结构。虽然您不会使用此方法来释放对视图对象的引用,但您可以使用它来释放您尚未在viewDidUnload方法中发布的任何与视图相关的数据结构。 (视图对象本身应始终在viewDidUnload方法中释放。)

     

viewDidUnload

     

您可以使用viewDidUnload方法释放视图特定的任何数据,并且如果视图再次加载到内存中,则可以轻松地重新创建。但是,如果重新创建数据可能过于耗时,则不必在此处释放相应的数据对象。相反,您应该考虑在didReceiveMemoryWarning方法中释放这些对象。

     

http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/BasicViewControllers/BasicViewControllers.html

  1. 对于didReceiveMemoryWarning,我们建议取消分配非关键数据结构。那么,什么是关键,什么是非关键?

  2. 此外,它还说要发布我们尚未在viewDidUnload中发布的内容。 但是当存在内存警告时,调用didReceiveMemoryWarning并且可以卸载视图,然后调用viewDidUnload。那么,它是在谈论将这些代码移动到前一个事件的方法(didReceiveMemoryWarning)还是我错过了一些关于事件顺序的东西?

  3. 对于viewDidUnload,我们建议在重新加载视图时关心轻松重新创建数据。 因此,如果视图正在使用且无法卸载,为什么我们会在didReceiveMemoryWarning中释放耗时的数据?发布这些数据后,当用户尝试在当前视图中执行某些操作时,加载它们也会非常耗时。

2 个答案:

答案 0 :(得分:16)

首先,这些只是指导原则,所以如果您认为在didReceiveMemoryWarning中发布内容是不合理的,那么就不要这样做。但请记住,如果您的应用程序首先导致内存警告,那么它最终将被操作系统终止。

Re(1):严重与非关键完全是你的召唤。只有您才能真正确定您认为关键的数据。虽然它可能与你的(3)密切相关,也就是说,容易重新创建的东西可能并不太关键。

Re(2):我认为该陈述不参考呼叫的顺序。正如您所意识到的那样,通常viewDidUnload将在didReceiveMemoryWarning之后被调用(因为didReceiveMemoryWarning可以导致viewDidUnload被调用)。例如,在viewDidUnload中,将释放从笔尖持有UI元素的引用。所以不要在didReceiveMemoryWarning中发布它们。

Re(3):如果一个视图正在使用中,因此无法卸载,那么是的,显然在didReceiveMemoryWarning中释放它并不一定有意义。但是,您可能实际上有一个实例无法卸载视图,但已知不可见(非常不正常),在这种情况下卸载它的数据并在视图再次可见时重新创建它是有意义的

此外,我同意“相反,你应该考虑......”这些言论有点奇怪,但我认为在didReceiveMemoryWarning中发布数据的重点是因为如果你'收到这些警告然后你自己的应用程序可能有被终止的危险。因此,虽然目前的情况是viewDidUnload可能总是被称为内存警告的结果,但未来可能并非总是如此,因此从概念上讲,在{{1}中释放数据更有意义本身。在didReceiveMemoryWarning你知道存在压力,didReceiveMemoryWarning你可能不会。因此,虽然重新创建数据的确很昂贵,但这可能比终止应用程序更好。对于用户来说,它似乎就像应用程序崩溃一样。

我个人对这些方法的态度通常是这样的:

  • viewDidUnload - 释放对从笔尖加载的UI元素的任何引用。在viewDidUnload
  • 中释放我自己创建的所有UI元素
  • didReceiveMemoryWarning - 释放在UI演示中使用的任何数据,如果/再次调用viewDidLoad(或某些其他应用程序特定事件),我可以重新创建。不要发布任何我无法重现的东西。

答案 1 :(得分:1)

我正在构建的应用程序是图形密集型的,无论是在布局镶边方面,还是在与我正在下载和显示的数据相关联的图像中。

我的didReceiveMemoryWarning方法完全是关于确定我在内存中保存但当前没有显示的图像,并将它们从内存中删除。另一部分是,您需要在显示图像之前检查它是否仍然存在,如果没有,则需要进行延迟加载。