如何知道NSAssert是否在发布版本中被禁用?
我经常在iOS代码中看到“断言”,我谷歌它,并知道它声称真假。
我想知道这是否会在发布模式下自动禁用?
使用NSAssert()及其同伴。
在项目中为你的发布configuration定义NS_BLOCK_ASSERTIONS
。
Xcode 4 tremplates在发布configuration中禁用NSAsserts
。 它补充说
-DNS_BLOCK_ASSERTIONS=1
到“其他C标志”为“发布”。
从文档:
如果定义了预处理器macrosNS_BLOCK_ASSERTIONS
则断言将被禁用。
NSAssertmacros评估条件,并作为断言处理程序的前端。
每个线程都有自己的断言处理程序,它是NSAssertionHandler
类的一个对象。 调用时,断言处理程序将打印包含方法和类名称(或函数名称)的错误消息。 然后引发一个NSInternalInconsistencyException
exception。 如果条件的计算结果为NO,则macros在当前线程的断言处理程序中调用handleFailureInMethod:object:file:lineNumber:description:
将desc作为描述string传递。
这个macros只能在Objective-C方法中使用。
我会在这里提供一个元回答:
@CocoaFu和@dasblinkenlight都是正确的。 NS_BLOCK_ASSERTIONS
closuresNSAssert()
和NDEBUG
closuresassert()
。 如果你同时使用两个,你需要两个。
更新: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
有效。)