我经常在 iOS 代码中看到“assert”,我用 google 搜索一下,然后知道它断言 true 或 false。
我想知道这是否会在发布模式下自动禁用?
使用 NSAssert() 及其同伴。
在项目中为您的发布配置定义
NS_BLOCK_ASSERTIONS
。
Xcode 4 在发布配置中禁用
NSAsserts
。它添加了
-DNS_BLOCK_ASSERTIONS=1
到“其他 C 标志”进行“释放”。
来自文档:
如果定义了预处理器宏
NS_BLOCK_ASSERTIONS
,则断言将被禁用。
NSAssert 宏评估条件并充当断言处理程序的前端。
每个线程都有自己的断言处理程序,它是类
NSAssertionHandler
的对象。调用时,断言处理程序会打印一条错误消息,其中包括方法和类名称(或函数名称)。然后它会引发 NSInternalInconsistencyException
异常。如果条件计算结果为 NO,则宏在当前线程的断言处理程序上调用 handleFailureInMethod:object:file:lineNumber:description:
,并将 desc 作为描述字符串传递。
该宏只能在 Objective-C 方法中使用。
我将在这里提供一个元答案:
@CocoaFu 和 @dasblinkenlight 都是正确的。
NS_BLOCK_ASSERTIONS
关闭 NSAssert()
,NDEBUG
关闭 assert()
。如果您同时使用,则两者都需要。
正如 Zaph 所说,
-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
标志的情况下运行。
如果您使用 swift 包管理器,则需要在目标级别禁用断言。包不会从您的 Xcode 项目中获取构建设置。
.target(
name: "ObjcPackage",
dependencies: [],
path: "include",
cxxSettings: [.define("NS_BLOCK_ASSERTIONS", .when(configuration: release))]
),