iOS:didReceiveMemoryWarning 的帮助:
Posted
技术标签:
【中文标题】iOS:didReceiveMemoryWarning 的帮助:【英文标题】:iOS: helpfulness of didReceiveMemoryWarning: 【发布时间】:2010-10-09 14:30:53 【问题描述】:我正在开发过程中跟踪崩溃和内存泄漏。作为一种策略,您是否将任何 NSLog 消息或某些此类通知放入 didReceiveMemoryWarning:
?此方法的文档相当稀少。准确地说,在崩溃发生之前,UIViewController 会触发该方法吗?在使用 Instruments 之前,这是一个起点吗?
【问题讨论】:
【参考方案1】:好的,有几点需要注意:
didReceiveMemoryWarning 将在内存不足崩溃之前调用。不是其他崩溃。如果您正确处理警告并释放内存,则可以避免内存不足的情况并且不会崩溃。 您可以在硬件菜单下的模拟器中手动触发内存警告。强烈建议这样做以测试您对 didReceiveMemoryWarning 的处理。 Instruments 可帮助您调试泄漏(尽管不是全部)- 它对崩溃并没有那么有用。 不,我个人不使用 NSLog - 我只是在调试时断点内存警告。【讨论】:
嗨 Airsource,我能问一下“模拟器 -> 硬件 -> 模拟内存警告”是做什么用的吗?每当我单击它时,我只会收到一条消息“收到模拟内存警告”。在控制台中。我如何使用它来“解决问题”?谢谢。 @lionfly - 为了响应内存警告,您应该尽可能多地释放内存。模拟内存警告可让您检查(和调试)该代码路径。【参考方案2】:如果用户让某些应用程序处于打开状态,那么可供您使用的内存将非常少。
所以有时候didReceiveMemoryWarning
只有在使用1MB后才能被系统调用。
系统会在所有视图控制器上调用此方法,如果您在每个视图控制器中放置一个 NSLog,您会注意到这一点。
然后,系统将自动在您的所有视图控制器(不是dealloc
)上调用方法viewDidUnload
。所以你必须把你所有的释放指令放在那里。
您必须进行大量实验,因为如果您的应用程序很复杂,您将面临很多崩溃,然后才能很好地管理它。
【讨论】:
【参考方案3】:更新
从 ios 6 开始,UIViewController
视图不再卸载以响应内存警告。相反,在调用didReceiveMemoryWarning
时,尽量释放您可以合理重新创建的任何资源(例如缓存的数据)。
更新 当我还是一个愤怒的年轻人时,我写下了我原来的答案;时代变了,基本上都是错的。
如果您有一个带有单个视图控制器的应用并且收到内存警告,那么您无能为力。但是,如果您有多个视图控制器,情况会发生巨大变化,因为您可以卸载 all 与非最前端控制器关联的状态。事实上,[UIViewController didReceiveMemoryWarning]
将通过为您卸载不可见的视图(惊喜!)来促使您朝着正确的方向前进。当最前面的视图控制器被关闭时,底层视图会重新加载,即使您的应用内部可能已经完全重启,用户最多也应该知道延迟。
这不是您可以轻松改造的一些细节,您需要从一开始就牢记内存使用情况,并将您的多视图应用程序设计成完全可卸载的UIViewController
部分。事实上,让你的代码与模拟器兼容只是为了使用它的内存警告功能是值得的。
当内存充足时,什么都没有卸载,一切都如丝般顺滑,当内存不足时,事情会继续工作,尽管速度会更慢。现在我要说,这种有限内存问题的解决方案是理想的。
要利用这个记忆客厅技巧,重载 UIViewController
方法
viewDidLoad
,viewDidUnload
, 和
viewWillUnload
(iOS5,如果卸载状态需要您的视图仍然存在,例如如果您不想泄漏 OpenGL 纹理和渲染缓冲区,则在 iOS4 上您可以通过重载 didReceiveMemoryWarning
并跟踪视图的可见性来模拟这一点) .
原创,更有胆量的答案
didReceiveMemoryWarning
绝对没用。
无法保证如果您释放内存(甚至全部) 你不会被杀。
在我的痛苦经历中,它通常在 2.x/3.0 上这样工作:
mediaserverd 泄露大量内存
我的应用程序被杀死
不幸的是,收割者从未想过要杀死 mediaserverd。
所以如果内存使用不是你的错,你真的只有 两个选择:
要求用户重启(用户认为是你的错,写了严厉的评论)
希望罪魁祸首崩溃(mediaserverd 经常有义务!)
【讨论】:
时间在前进。 viewDidUnload 现在被这些注释弃用了,“视图不再在内存不足的情况下被清除,所以这个方法永远不会被调用。”和“在 iOS 6 及更高版本中,不需要清除视图控制器中对视图和其他对象的引用。” - source 前几天我还在考虑更新这个答案!【参考方案4】:didReceiveMemoryWarning 的目的是让您有机会释放内存或弹出视图以避免崩溃。您不会在任何可预测的时间收到它,因为它取决于用户在做什么。例如,如果用户正在收听 iPod,则可用内存较少,您将更快收到。
一般的经验法则是您可以使用大约 8MB 的 RAM。当您接近它时,您可以预期该事件会被引发。如果你故意占用这么多内存,你应该有一个计划来解决它。
【讨论】:
以上是关于iOS:didReceiveMemoryWarning 的帮助:的主要内容,如果未能解决你的问题,请参考以下文章