我经常在iOS代码中看到“断言”,我谷歌它,并且知道它断言是真还是假。
我想知道这是否会在发布模式下自动禁用?
答案 0 :(得分:39)
使用NSAssert()及其随附数据。
项目中的为您的发布配置定义NS_BLOCK_ASSERTIONS
。
Xcode 4 tremplates在发布配置中禁用NSAsserts
。它增加了
-DNS_BLOCK_ASSERTIONS=1
到“释放”的“其他C标志”。
来自文档:
如果定义了预处理器宏NS_BLOCK_ASSERTIONS
,则会禁用断言。
NSAssert宏评估条件并充当断言处理程序的前端。
每个线程都有自己的断言处理程序,它是类NSAssertionHandler
的对象。调用时,断言处理程序会输出包含方法和类名(或函数名)的错误消息。然后它会引发NSInternalInconsistencyException
异常。如果condition的计算结果为NO,则宏在当前线程的断言处理程序上调用handleFailureInMethod:object:file:lineNumber:description:
,并将desc作为描述字符串传递。
此宏只能在Objective-C方法中使用。
答案 1 :(得分:36)
更新:已验证此功能也可在Xcode 8中使用。
在Xcode 7中,进入项目构建设置并在搜索栏中搜索“Assert”。这显示“Apple LLVM 7.0 - 预处理”部分。有一个名为“Enable Foundation Assertions”的设置。
我已经从那里成功启用/禁用了NSAssert。
答案 2 :(得分:25)
我将在这里提供一个元答案:
@CocoaFu和@dasblinkenlight都是正确的。 NS_BLOCK_ASSERTIONS
关闭NSAssert()
,NDEBUG
关闭assert()
。如果同时使用两者,则需要两者。
答案 3 :(得分:7)
正如扎普所说,-DNS_BLOCK_ASSERTIONS=1
即将发布。但是,如果你想检查一下。
首先在文档中观察宏NS_BLOCK_ASSERTIONS
禁用NSAssert。然后将其添加到构建中并观察它是否符合确定:
#ifdef NS_BLOCK_ASSERTIONS
#error Error - NS_BLOCK_ASSERTIONS is defined
#endif
然后将方案更改为释放(cmd - shift - <)
然后观察构建失败。因此,NS_BLOCK_ASSERTIONS
被定义为NSAssert
被禁用。
答案 4 :(得分:5)
在定义NDEBUG
时,会从代码中有条理地编译断言。如果在相应的构建设置部分中定义NDEBUG=1
,则无论发布或调试模式如何,都将在代码中停用断言。
答案 5 :(得分:2)
以下是我在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
有效。)
答案 6 :(得分:0)
现在,从Xcode 6开始,设置为ENABLE_NS_ASSERTIONS
,默认情况下,调试配置设置为1
,Release版设置为0
。
您可以通过传递ENABLE_NS_ASSERTIONS=1
参数来为命令行中的Release版本选择它,我正在执行该参数来运行检查断言条件的单元测试,否则应该使用{{1}运行旗帜关闭。