如何知道NSAssert是否在发布版本中被禁用?

我经常在iOS代码中看到“断言”,我谷歌它,并知道它声称真假。

我想知道这是否会在发布模式下自动禁用?

使用NSAssert()及其同伴。

在项目中为你的发布configuration定义NS_BLOCK_ASSERTIONS

Xcode 4 tremplates在发布configuration中禁用NSAsserts 。 它补充说

 -DNS_BLOCK_ASSERTIONS=1 

到“其他C标志”为“发布”。

从文档:

如果定义了预处理器macrosNS_BLOCK_ASSERTIONS则断言将被禁用。

NSAssertmacros评估条件,并作为断言处理程序的前端。

每个线程都有自己的断言处理程序,它是NSAssertionHandler类的一个对象。 调用时,断言处理程序将打印包含方法和类名称(或函数名称)的错误消息。 然后引发一个NSInternalInconsistencyExceptionexception。 如果条件的计算结果为NO,则macros在当前线程的断言处理程序中调用handleFailureInMethod:object:file:lineNumber:description:将desc作为描述string传递。

这个macros只能在Objective-C方法中使用。

我会在这里提供一个元回答:

@CocoaFu和@dasblinkenlight都是正确的。 NS_BLOCK_ASSERTIONSclosuresNSAssert()NDEBUGclosuresassert() 。 如果你同时使用两个,你需要两个。

更新:validation这个工程在Xcode 8也是如此。

在Xcode 7中,进入项目构build设置并在search栏中search“Assert”。 这显示了“Apple LLVM 7.0 – 预处理”部分。 有一个名为“启用基础声明”的设置。

我已经成功地启用/禁用NSAssert从那里。

在这里输入图像说明

正如Zaph所说的, -DNS_BLOCK_ASSERTIONS=1被设置为释放。 但是,如果你想检查这个。

首先在文档中观察NSAssert被macrosNS_BLOCK_ASSERTIONS禁用。 然后将其添加到构build并观察它是否符合要求:

 #ifdef NS_BLOCK_ASSERTIONS #error Error - NS_BLOCK_ASSERTIONS is defined #endif 

然后改变scheme释放(cmd – shift – <)

在这里输入图像说明

然后观察构build失败。 因此NS_BLOCK_ASSERTIONS被定义,意味着NSAssert被禁用。

定义NDEBUG时,断言是有条件地编译出来的。 如果在相应的构build设置部分中定义了NDEBUG=1 ,则无论发行版或debugging模式如何,都将停用代码中的断言。

现在,从Xcode 6开始,设置为ENABLE_NS_ASSERTIONS ,默认情况下,对于Debugconfiguration设置为1 ,对于Release为设置为0

您可以通过传递ENABLE_NS_ASSERTIONS=1参数来为发布版本在命令行上进行select,我正在为运行检查断言条件的unit testing进行操作,否则应该在DEBUG标志closures的情况下运行。

以下是我在main()的顶部所做的事情:

 #if defined(NDEBUG) { // The assertion code below should be compiled out of existence in a release // build. Log an error and abort the program if it is not. bool ok = true; NSCAssert(ok = false, @"NS assertions should be disabled but are not"); if (!ok) { NSLog(@"Detected release build but NS_BLOCK_ASSERTIONS is not defined"); return -1; } } #endif 

请注意,因为main()是C函数而不是Objective-C函数, NSCAssert在上面而不是在NSAssert 。 ( NSAssert期望self有效。)