【问题标题】:Avoiding fatal crashes避免致命的崩溃
【发布时间】:2018-04-23 20:07:41
【问题描述】:

我已经调试了一段时间的应用程序,并准备将其上传到应用商店。但是,我仍然偶尔会遇到难以复制或调试的崩溃——例如以奇怪的顺序按下按钮时。如果我把这些序列写下来,我可以调试,但当我没有写下来时不可避免地会发生这种情况,而且这些序列可能难以复制。

我知道我需要收工并将未来的错误修复留到下一个版本。我已经删除了我在测试中的所有 abort() 语句。但是,有时我不会遇到让您关闭应用程序并重新打开的崩溃,而是会遇到一个导致无法在不重新安装的情况下打开应用程序的崩溃。例如,这刚刚发生,带有

'NSGenericException',原因:'*** Collection <__nscfset:> 在枚举时发生了变异。'

这是在后台同步到云期间切换 VC 造成的。

我可以忍受只需要重新打开的崩溃,但不能忍受导致应用程序无法使用的崩溃。是否有任何针对崩溃类型的指南来帮助您专注于真正致命的崩溃?

或者有什么办法可以防止应用程序崩溃?

【问题讨论】:

  • 解决根本原因。确保您的代码是线程安全的。
  • 似乎是竞争条件的问题。

标签: ios objective-c debugging crash


【解决方案1】:

你应该解决这个问题。由于您拥有带有该错误消息的崩溃日志,因此您知道哪种方法会引发问题,因此您在修复它方面有一个良好的开端,即使问题以不一致的方式和/或以多种方式表现出来。

但偶尔的崩溃对您来说似乎并没有太大的不便,但它是获得 1 星评价和不满意客户的最快方式。我怀疑你很快就会后悔发布一个已知的、容易重现的崩溃的应用程序。

但是,有一些观察:

  1. 听起来您的后台更新过程正在改变主线程使用的模型对象。

    • 如果可能的话,我建议小心不要在后台线程中更改任何模型对象,而是填充一个局部变量,当您准备好相应地更新 UI 时,同时调度这两个模型更新和 UI 刷新到主线程。

    • 如果由于某种原因无法做到这一点,则必须使用锁、GCD 串行队列、读写器模型等机制来同步模型更新的所有交互。这种方法稍微复杂一些,但是可以的。

  2. 我建议暂时编辑你的目标的“方案”并打开线程清理器:

    它可能会帮助您识别并更轻松地重现这些问题。您越容易重现问题,就越容易解决问题。

  3. 你说:

    或者有什么办法可以防止应用程序崩溃?

    听起来“保存”操作以某种方式将结果以内部不一致的方式留在持久存储中。以下任何一项都会有所帮助,但我建议您尽可能做这三项):

    • 冒着重蹈覆辙的风险,修复崩溃(消除问题的根源总是比试图围绕问题的表现进行编程更好);

    • 根据您保存结果的方式,您可以使用atomic 保存操作,这样如果中途失败,它不会使其处于不一致状态;如果没有看到代码 sn-p 说明您如何保存结果,我们无法建议您应该如何执行此操作,但这通常是一种选择;

    • 确保,如果读取持久存储的“加载”进程可能失败,它会优雅地执行此操作,而不是崩溃;看看您是否可以在应用程序在启动期间失败的状态下获取它,然后仔细调试启动过程中发生的事情,导致应用程序在持久存储中使用此特定数据集失败。在“设备”部分,可以选择下载与应用相关的数据,以便您仔细诊断发生的情况。

【讨论】:

  • 感谢您提供如此详尽的回答。关于您的第一段,有一种方法可以从上面的错误消息中判断是什么方法导致了崩溃。了解崩溃的位置将有助于调试。
  • 如果您可以在调试器中(在设备上或模拟器上)运行应用程序时显示崩溃,这是最简单的,因为您可以直接在 Xcode 中查看堆栈跟踪。如果您遇到崩溃日志,您可能需要“符号化”它们(将神秘地址转换为代码行;请参阅TN2151)。
  • 我打开了线程清理器并暂停了问题,果然,应用程序正在暂停,只显示黑屏。但是,在控制台中没有看到任何提示原因。我应该去哪里看?
  • 应用中的“黑屏”?没关系。我们更关心应用程序而不是 Xcode 中的堆栈跟踪。我不可能在 cmets 中向您介绍这一点,但我可能建议您观看 WWDC 2016 视频 Thread Sanitizer and Static Analysis 或 WWDC 2017 Finding Bugs using Xcode Runtime Tools。我认为这些包括有关如何使用该工具的实际演示。对不起,我帮不上什么忙。 ;(
  • 好的。谢谢,我看了视频,非常有帮助。我的应用程序没有出现任何问题,但由于应用程序未在模拟器中启动,我无法尝试所有操作。我会继续努力。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-04
  • 1970-01-01
  • 1970-01-01
  • 2021-10-03
  • 2014-09-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多