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

问题描述 投票:0回答:8

我经常在 iOS 代码中看到“assert”,我用 google 搜索一下,然后知道它断言 true 或 false。

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

ios objective-c xcode
8个回答
52
投票

更新: 已验证这也适用于 Xcode 8。

在 Xcode 7 中,进入项目构建设置并在搜索栏中搜索“Assert”。这显示了“Apple LLVM 7.0 - 预处理”部分。有一个名为“启用基础断言”的设置。

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


48
投票

使用 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 方法中使用。


36
投票

我将在这里提供一个元答案:

@CocoaFu 和 @dasblinkenlight 都是正确的。

NS_BLOCK_ASSERTIONS
关闭
NSAssert()
NDEBUG
关闭
assert()
。如果您同时使用,则两者都需要。


8
投票

正如 Zaph 所说,

-DNS_BLOCK_ASSERTIONS=1
已准备好发布。但是,如果您想检查这一点。

首先在文档中观察到 NSAssert 被宏

NS_BLOCK_ASSERTIONS
禁用。然后将其添加到构建中并观察它是否符合要求:

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

然后更改方案以释放(cmd - shift - <)

enter image description here

然后观察构建失败。因此

NS_BLOCK_ASSERTIONS
的定义意味着
NSAssert
被禁用。


5
投票

定义

NDEBUG
时,断言将有条件地从代码中编译出来。如果您在相应的构建设置部分中定义
NDEBUG=1
,则无论发布或调试模式如何,您都将停用代码中的断言。


3
投票

这是我在

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
有效。)


1
投票

现在,从 Xcode 6 开始,设置为

ENABLE_NS_ASSERTIONS
,默认情况下,调试配置设置为
1
,发布配置设置为
0

您可以通过传递

ENABLE_NS_ASSERTIONS=1
参数来选择在命令行上进行发布构建,我这样做是为了运行检查断言条件的单元测试,但否则应在关闭
DEBUG
标志的情况下运行。


0
投票

如果您使用 swift 包管理器,则需要在目标级别禁用断言。包不会从您的 Xcode 项目中获取构建设置。

.target(
    name: "ObjcPackage",
    dependencies: [],
    path: "include",
    cxxSettings: [.define("NS_BLOCK_ASSERTIONS", .when(configuration: release))]
),
© www.soinside.com 2019 - 2024. All rights reserved.