我经常在iOS代码中看到"assert",我谷歌了一下,知道它是断言真或假。
我想知道它是否会在发布模式下自动禁用?
我经常在iOS代码中看到"assert",我谷歌了一下,知道它是断言真或假。
我想知道它是否会在发布模式下自动禁用?
使用NSAssert()及其相关方法。
在项目中为你的发布配置定义NS_BLOCK_ASSERTIONS
。
Xcode 4模板会在发布配置中禁用NSAsserts
。它会添加
-DNS_BLOCK_ASSERTIONS=1
针对“Release”配置,将代码中的C标志更改为“其他 C 标志”。
根据文档:
如果预处理器宏 NS_BLOCK_ASSERTIONS
被定义,则禁用断言。
NSAssert
宏评估条件并作为断言处理程序的前端。
每个线程都有自己的断言处理程序,它是NSAssertionHandler
类的对象。当调用时,断言处理程序会打印包括方法和类名(或函数名)在内的错误消息。然后,它会引发一个 NSInternalInconsistencyException
异常。如果条件求值为 NO,则该宏会在当前线程的断言处理程序上调用handleFailureInMethod:object:file:lineNumber:description:
,并将 desc 作为描述字符串传递。
此宏仅应在 Objective-C 方法中使用。
我在这里提供一个元回答:
@CocoaFu 和 @dasblinkenlight 都是正确的。 NS_BLOCK_ASSERTIONS
关闭了 NSAssert()
,NDEBUG
关闭了 assert()
。如果你同时使用两者,则两者都需要。
-DNDEBUG=1
的形式,使用-D来指定宏定义。 - Kekoa-DNS_BLOCK_ASSERTIONS=1
在发布时被设置。但是,如果您想要检查这一点,请首先观察文档,了解NSAssert由宏NS_BLOCK_ASSERTIONS
禁用。然后将其添加到构建中并观察它是否编译通过。#ifdef NS_BLOCK_ASSERTIONS
#error Error - NS_BLOCK_ASSERTIONS is defined
#endif
然后将方案更改为发布(cmd-shift-<)
然后观察构建失败。因此,定义了NS_BLOCK_ASSERTIONS
,意味着NSAssert
被禁用。
当定义了NDEBUG
时,断言将被有条件地编译出代码。如果在对应的构建设置部分中定义NDEBUG=1
,则无论是发布模式还是调试模式,都会停用代码中的断言。
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
是有效的。)从 Xcode 6 开始,设置是 ENABLE_NS_ASSERTIONS
,默认情况下对于调试配置设置为 1
,而对于发布配置设置为 0
。
你可以通过在命令行中传递 ENABLE_NS_ASSERTIONS=1
参数来选择在发布版本中采用它,我在运行检查断言条件的单元测试时会这样做,但否则应该关闭 DEBUG
标志。