是否应该在生产iOS应用中留下断言?

hot*_*aw2 9 iphone assert ios

通常的做法可能是在应用程序开发期间将断言放入代码中以检查输入参数,数据完整性等.

我测试我的应用程序,但是,鉴于我不是Knuth(并且写了1美元的支票),而且我不能像一些医疗和太空系统软件公司那样雇用一支庞大的全职QA团队,我假设所有应用程序总是会有大量的错误,这些错误在测试或质量检查期间从未见过.假设在其他方面似乎非常不诚实.因此,在测试应用程序(显然删除导致任何先前看到的ASSERT失败的所有错误)并准备好将应用程序发送给Apple之后,应该如何处理发布/分发版本中的所有ASSERT检查?请假或禁止?

这里有一个理由让他们离开:如果一个应用程序对某些用户来说很不稳定,那么该应用程序可能会被这些用户评为1星级,而没有人告诉开发人员为什么足够详细.但是如果应用程序因ASSERT故障而崩溃,那么应用程序可能仍然会被评为1星级,但是如果有足够多的用户选择进入,开发人员可能通过iTunes和iTunes Connect间接获得一些故障转储,以找出问题所在.如果苹果公司因全新的ASSERT崩溃而被Apple拒绝,这将阻止该应用程序的恶劣版本进入客户的设备.

Dan*_*ark 11

将它们保留在您指定的原因中,但也因为在某些情况下它们充当注释(特别是在Objective-C中涉及类型的情况).并且不要担心性能损失,除非它成为问题或者您知道您处于性能危急情况并且特定断言将在主运行循环中运行数百或数千次.

无法抗拒关于断言与NSAssert的这篇文章.

就个人而言,我开始删除我为调试目的而放入的那些,但是如果你使用asserts来检查数据完整性,参数,资源依赖性和其他相关的东西 - 可以说,你可以自己抛出异常,这可能是更聪明 - 然后我会留下他们.

注意:另一点是,删除断言完全是愚蠢的,因为您的应用程序将崩溃或处于不一致状态,这两种情况都比崩溃日志中可识别的崩溃更糟糕(因此请保留断言)在).if另一方面,用语句替换断言可能是件好事.


jus*_*tin 5

我的建议:你应该默认将它们保持为ON.我说:"努力工作,尽早失败" - 并将错误修正保持在比功能更高的优先级.

但是,选择也很好 - 我不认为一个尺寸适合所有程序.出于这个原因,我使用了多种类型的断言.有些将在发布,有些则不会.我写了很多错误检测,我还写了很多性能关键程序.我不能在发布版本的热门路径中留下大量的诊断和健全性检查.

不幸的是,它不能成为事后的想法(除非您准备优先考虑质量和测试开放时间).如果你考虑一下,单一/传统方法也不能成为事后的想法.对于任一模型,最好编写程序之前决定是否在发布时启用断言或哪些断言.


所以双断言模型的基本一般形式可能如下所示:

#include <assert.h>

/*
  MONDebugAssert assertion is active in debug and disabled in release.
  Recommendation: Always define NDEBUG (or not) in your build settings, 
  and nowhere else.
*/
#if defined(NDEBUG)
    #define MONDebugAssert(e) ((void)0)
#else
    #define MONDebugAssert(e) \
        (__builtin_expect(!(e), 0) ? __assert(#e, __FILE__, __LINE__) : (void)0)
#endif

/* MONAssert assertion is active at all times, including release builds. */
#define MONAssert(e) \
       (__builtin_expect(!(e), 0) ? __assert(#e, __FILE__, __LINE__) : (void)0)
Run Code Online (Sandbox Code Playgroud)

__assert平台断言处理程序在哪里.

然后在使用中:

MONDebugAssert(0); // << will fail in debug, and not in release.
MONAssert(0); // << will fail in any case
Run Code Online (Sandbox Code Playgroud)

当然,很容易适应您的需求,或创建self假定在范围内的变体(如NSAssert).