【问题标题】:iOS: Detect low-memory crash outside of main run loopiOS:检测主运行循环之外的低内存崩溃
【发布时间】:2013-02-15 18:31:17
【问题描述】:

在我的一个应用程序中,我进行了大量涉及数组的计算并将它们绘制成图形。计算涉及用户输入,有时,如果用户输入疯狂的值,应用程序将继续执行计算,直到它占用太多内存并被杀死。当用户再次尝试打开应用程序时,它将尝试从上次保存的数据中进行相同的计算并再次崩溃。用户需要删除并重新下载应用程序才能恢复为默认值。

为了解决这个问题,我想在应用程序因内存不足而被终止时转储所有保存的数据。我尝试在我的 appDelegate 中实现 applicationDidReceiveMemoryWarning: 并在进行计算的 viewController 中实现 didReceiveMemoryWarning:。这些函数都没有被调用。在researching a bit之后,我发现是因为我阻塞了主运行循环。

我怎样才能最好地处理这种情况?

【问题讨论】:

  • 在后台线程中执行计算?
  • 计算后,我需要更新 UI 并进行一些自定义绘图。如果我在后台线程上执行计算,则会调用内存警告,但我的图表并不总是正确显示。

标签: iphone ios objective-c memory-management didreceivememorywarning


【解决方案1】:

您基本上不应该阻塞主运行循环。您可以阻止用户界面(使用模式加载屏幕或类似屏幕),但如果您阻止主运行循环,您将面临各种问题。

有很多方法可以将您的工作转移到辅助线程 - 最简单/最高级别的选项之一是使用 performSelectorInBackground:。如果您需要更有限的控制,您可以使用NSOperationNSOperationQueue,或者一直到 GCD(希望您不需要达到这个低级别)。

将工作放在辅助/后台线程上的另一个好处是,如果操作似乎花费了太长时间,您可以让用户取消操作,也许可以通过“取消”按钮。当用户点击它时,您可以取消正在进行的操作,并避免这些内存警告首先发生。

但不要忘记任何 UI 工作都需要在主线程上进行。因此,一旦您完成了处理,请确保在主线程上更新图形本身(使用 performSelectorOnMainThread 等)。

【讨论】:

  • 我必须创建一些新函数,以便在正确的线程上以正确的顺序调用所有内容,但它现在可以工作了!感谢您的帮助!
  • GCD 不是应该避免的,因为它是“低级”的。它实际上是迄今为止在后台线程上运行的最简单的方法。也意味着您不必创建新方法。
猜你喜欢
  • 2011-08-24
  • 2012-05-07
  • 1970-01-01
  • 1970-01-01
  • 2015-05-02
  • 2012-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多