iOS:didReceiveMemoryWarning的帮助:

我是我的开发过程中追踪崩溃和内存泄漏的一部分。 作为一个策略,你是否把任何NSLog的消息或一些这样的通知didReceiveMemoryWarning: 这个方法的文档相当稀less。 是否准确地说,在发生崩溃之前,UIViewController会触发该方法? 即使是与仪器一起前进,这是一个起点吗?

好的,有几件事要注意:

  • didReceiveMemoryWarning将在内存不足崩溃之前调用。 没有其他崩溃。 如果正确处理警告并释放内存,则可以避免出现内存不足的情况,也不会崩溃。
  • 您可以在硬件菜单下的模拟器中手动触发内存警告。 强烈build议您这样做来testing您对didReceiveMemoryWarning的处理。
  • 仪器可以帮助你debugging泄漏(尽pipe不是全部) – 对于崩溃并不是那么有用。
  • 不,我不亲自使用NSLog – 我只是在debugging时断开内存警告。

如果用户留下了一些应用程序,您可以使用的内存很less。 所以有时候,只有在1 MB的使用量之后,系统才会调用didReceiveMemoryWarning

系统在所有视图控制器上调用这个方法,如果你在每个视图控制器中放置一个NSLog,你会注意到这一点。

然后自动的方法viewDidUnload将由系统在您的所有视图控制器(而不是dealloc )调用。 所以你必须把所有的释放指令放在那里。

你必须进行大量的实验,因为如果你的应用程序是复杂的,那么在pipe理它之前你会遇到很多崩溃。

更新从iOS 6开始, UIViewController视图不再被卸载以响应内存警告。 相反,只要尽力释放任何资源,您可以合理地重新创build(如caching数据),当didReceiveMemoryWarning被调用。

UPDATE
当我是一个愤怒的年轻人,我写了我原来的答案; 时代已经改变,基本上,这是错误的。

如果你有一个单一的视图控制器的应用程序,并收到内存警告,你可以做的事情不多。 但是如果你有多个视图控制器的话,事情会发生巨大的变化,因为你可以卸载与非最前面的控制器相关的所有状态。 事实上, [UIViewController didReceiveMemoryWarning]会通过卸载不可见的视图给你正确的方向(惊喜!)。 当最前面的视图控制器被解散时,底层视图被重新加载,并且至多用户应该只知道延迟,即使在内部你的应用可能已经完成了重新启动。

这不是一些细节,你可以很容易地翻新,你需要从头开始记住内存使用,并devise你的多视图应用程序到干净的无法加载UIViewController件。 事实上,值得让你的代码与模拟器兼容,只是为了使用它的内存警告function。

当记忆丰富的时候,没有什么东西是卸载的,一切都是如丝般光滑的,而当记忆力低下的时候,事情会继续下去,尽pipe比较缓慢。 现在我想说这个有限内存问题的解决scheme是理想的。

为了充分利用这个内存技巧,重载UIViewController方法viewDidLoadviewDidUnloadviewWillUnload (iOS5,如果卸载状态需要你的视图依然存在,例如如果你不想泄露你的OpenGL纹理和渲染缓冲区,您可以通过重载didReceiveMemoryWarning和跟踪您的视图的可见性来模拟iOS4。

原来的,更有生气的答案

didReceiveMemoryWarning绝对没用。

没有保证,如果你释放记忆(甚至所有的),你不会被杀死。

在我的痛苦经历中,它通常在2.x / 3.0上是这样工作的:

  1. mediaserverd泄漏了一堆内存

  2. 我的应用程序被杀害

不幸的是,收割者从来没有想过杀死mediaserverd。

所以,如果内存使用不是你的错,你真的只有两个select:

  1. 要求用户重新启动(用户认为这是你的错,写一个严厉的评论)

  2. 希望肇事者崩溃(mediaserverd经常要求!)

didReceiveMemoryWarning的目的是为了让您有机会释放内存或popup视图,以避免崩溃。 你不会在任何可预测的地方收到它,因为它取决于用户在做什么。 例如,如果用户正在聆听iPod,则可用内存会减less,您将会收到更快的内存。

一般的经验法则是,你有大约8MB的RAM工作。 当你接近的时候,你可以期待事件被提出。 如果你故意占用那么多RAM,你应该有一个计划去做一些事情。