【问题标题】:How to make Crash resistant ios apps如何制作防崩溃的 iOS 应用程序
【发布时间】:2012-08-13 23:00:49
【问题描述】:

我现在正在编写 ios 应用程序一段时间。但是我的应用程序仍然经常崩溃,并且需要时间才能使它们非常稳定。我觉得这很烦人。

那么,有没有关于防崩溃编程 iOS 应用程序的编程模式?

【问题讨论】:

  • 使用 Xcode 分析功能,启用 Zombie Objects,使用 Instruments。

标签: ios design-patterns crash


【解决方案1】:
  • 打开编译器警告。删除所有警告。
  • 运行静态分析器。删除所有警告。
  • 使用 GuardMalloc 和/或 Scribbling 运行。
  • 删除所有泄漏
  • 移除所有僵尸
  • 编写单元测试
  • 编写高级实时错误检测(例如断言)
  • 在添加功能之前修复错误。
  • 使用源代码控制和持续集成。
  • 阅读。改进。

【讨论】:

    【解决方案2】:

    1) 使用 ARC。

    ARC 的学习曲线很小,我在 SO 上读到的一个大问题是人们实例化对象但忘记将对象分配给强 ivar(或属性),因此对象神秘地消失了。无论如何,好处是如此引人注目,您应该掌握这一点。当您这样做时,您必须立即保留的大部分内存管理内容都会消失。

    2) 构建干净

    您在构建时永远不应该出现警告。如果你有一堆,当一个真正的问题出现时,它就会被你习惯于忽略的垃圾线埋没。专业程序员构建干净。

    3) 使用分析

    Xcode/llvm 有一个非凡的分析器 - 使用它 - 它位于 Product 菜单项下。然后清理它给你的每一个警告。

    4) 使用正确的配置

    我总是有一个发布(或分发)配置、一个 ReleaseWithAsserts 和一个调试。我只在使用 lldb 时使用 Debug,因为代码要大得多,并且它的执行方式与优化的编译方式不同。 ReleaseWithAsserts 与 Debug 类似,但去掉了 Debug=1 预处理器标志,并将优化器设置为 -Os(Release 的默认值)。

    最后,Release/Distribution 配置在 Preprocessing Macros 中有以下内容:

    NS_BLOCK_ASSERTIONS=1 NDEBUG
    

    第一个关闭所有“NSAssert()”行,第二个关闭所有“assert()”语句。这样,您的交付代码中就没有任何断言处于活动状态

    5) 使用大量的断言。

    断言是作为程序员可以拥有的最好的朋友之一。我在这里看到了很多问题,如果程序员只使用它们就永远不会写出来。开销在于键入它们,因为(在我的使用中)它们在发布配置中被编译掉。

    每当你从另一个来源获得一个对象时,断言它的存在(即:

    MyObject *foo = [self someMethod];
    assert(foo);
    

    这很容易输入,但是当一个 nil 对象在数千条指令之后导致问题时,可以节省您数小时的调试时间。你也可以在类上断言:

    MyObject *foo = [self someMethod];
    assert([foo isMemberOfClass:[MyObject class]]);
    

    这在您从字典中提取对象时特别有用。

    您可以将断言放在方法的开头,以验证您收到的对象也不是 nil。

    你可以断言某个变量有一个值:

    assert(i>1 && i<5);
    

    同样,除了 Release/Distribution 配置,断言是“实时的”,但在该配置中它们被编译出来。

    NSAssert 类似 - 但您必须根据参数的数量使用不同的宏。

    NSAssert(foo, @"Foo was nil");
    NSAssert1(foo, @"Foo was nil, and i=%d", i);
    ...
    

    6) 使用选择性日志来确保应该发生的事情是

    您可以定义自己的日志宏,该宏会被编译出来用于发布/分发。将此添加到您的 pch 文件中:

    #ifndef NDEBUG
    
    #define MYLog NSLog
    
    #else
    
    #define MYLog(format, ...)
    
    #endif
    

    这指出了另一点 - 你可以使用:

    #ifndef NDEBUG
    ...
    #endif
    

    屏蔽一些执行更复杂检查的代码 - 它只对您的开发构建有效,而不是用于发布/分发。

    【讨论】:

      【解决方案3】:

      你可能已经做了这些,但这是我做的:

      1. 使用调试器/模拟器转到应用程序中的每个屏幕,然后选择“模拟内存警告”。返回上一个屏幕。这会导致 viewDidLoad 中现有的 UIView 对象和变量分配被重新分配(这可能导致错误的指针引用)。

      2. 确保在 dealloc 中使所有正在运行的计时器无效。

      3. 如果对象 A 已将自己设为对象 B 的委托,请确保在对象 A 的 dealloc 中将其清除。

      4. 确保清除 dealloc 中的所有通知观察者。

      【讨论】:

      • RE: 2) - 定时器保持自我,所以如果你有活跃的定时器,你就不会去dealloc。
      猜你喜欢
      • 1970-01-01
      • 2011-10-13
      • 1970-01-01
      • 1970-01-01
      • 2013-03-08
      • 2018-02-12
      • 2012-03-27
      • 2018-07-17
      • 1970-01-01
      相关资源
      最近更新 更多