ios 如何知道在发布版本中是否禁用了 NSAssert?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8552486/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to know if NSAssert is disabled in release builds?
提问by qichunren
I often saw "assert " in iOS code, I google it, and got to know it assert true or false.
我经常在 iOS 代码中看到“断言”,我谷歌了一下,才知道它断言是真还是假。
I want to know if this will auto disable in release mode?
我想知道这是否会在发布模式下自动禁用?
回答by zaph
Use NSAssert() and its companions.
使用 NSAssert() 及其同伴。
in the project define NS_BLOCK_ASSERTIONS
for your release configuration.
在项目中NS_BLOCK_ASSERTIONS
为您的发布配置定义。
Xcode 4 tremplates disable NSAsserts
in the release configuration. It adds
Xcode 4 模板NSAsserts
在发布配置中禁用。它增加了
-DNS_BLOCK_ASSERTIONS=1
to "Other C Flags" for "Release".
到“其他 C 标志”为“发布”。
From the documentation:
从文档:
Assertions are disabled if the preprocessor macro NS_BLOCK_ASSERTIONS
is defined.
如果NS_BLOCK_ASSERTIONS
定义了预处理器宏,则断言将被禁用。
The NSAssert macro evaluates the condition and serves as a front end to the assertion handler.
NSAssert 宏评估条件并用作断言处理程序的前端。
Each thread has its own assertion handler, which is an object of class NSAssertionHandler
. When invoked, an assertion handler prints an error message that includes the method and class names (or the function name). It then raises an NSInternalInconsistencyException
exception. If condition evaluates to NO, the macro invokes handleFailureInMethod:object:file:lineNumber:description:
on the assertion handler for the current thread, passing desc as the description string.
每个线程都有自己的断言处理程序,它是 class 的一个对象NSAssertionHandler
。调用时,断言处理程序会打印一条错误消息,其中包括方法和类名(或函数名)。然后它引发NSInternalInconsistencyException
异常。如果条件评估为 NO,则宏调用handleFailureInMethod:object:file:lineNumber:description:
当前线程的断言处理程序,将 desc 作为描述字符串传递。
This macro should be used only within Objective-C methods.
这个宏应该只在 Objective-C 方法中使用。
回答by Jeff
Update:Verified this works in Xcode 8 as well.
更新:验证这也适用于 Xcode 8。
In Xcode 7, go into the project build settings and search for "Assert" in the search bar. This shows section "Apple LLVM 7.0 - Preprocessing" section. There is a setting named "Enable Foundation Assertions".
在 Xcode 7 中,进入项目构建设置并在搜索栏中搜索“Assert”。这显示了“Apple LLVM 7.0 - 预处理”部分。有一个名为“启用基础断言”的设置。
I have successfully enabled/disabled NSAssert from there.
我已经从那里成功启用/禁用了 NSAssert。
回答by Rob Napier
I will here provide a meta-answer:
我将在这里提供一个元答案:
Both @CocoaFu and @dasblinkenlight are correct. NS_BLOCK_ASSERTIONS
turns off NSAssert()
and NDEBUG
turns off assert()
. You need both if you use both.
@CocoaFu 和 @dasblinkenlight 都是正确的。NS_BLOCK_ASSERTIONS
关闭NSAssert()
并NDEBUG
关闭assert()
。如果您同时使用两者,则两者都需要。
回答by Robert
As Zaph said -DNS_BLOCK_ASSERTIONS=1
is set for release. However, if you wanted to check this.
正如 Zaph 所说,-DNS_BLOCK_ASSERTIONS=1
即将发布。但是,如果你想检查这个。
First observe in the docs that NSAssertis disabled by the macro NS_BLOCK_ASSERTIONS
. Then add this to the build and observe it complies ok:
首先在文档中观察NSAssert被宏禁用NS_BLOCK_ASSERTIONS
。然后将其添加到构建中并观察它是否符合:
#ifdef NS_BLOCK_ASSERTIONS
#error Error - NS_BLOCK_ASSERTIONS is defined
#endif
Then change the scheme to release (cmd - shift - <)
然后改变方案释放(cmd - shift - <)
Then observe that the build fails. Therefore NS_BLOCK_ASSERTIONS
is defined meaning NSAssert
s are disabled.
然后观察构建失败。因此NS_BLOCK_ASSERTIONS
,定义意味着NSAssert
s 被禁用。
回答by dasblinkenlight
Asserts are conditionally compiled out of your code when NDEBUG
is defined. If you define NDEBUG=1
in the corresponding build settings section, you will deactivate asserts in your code regardless of the release or debug mode.
断言在NDEBUG
定义时有条件地从您的代码中编译出来。如果您NDEBUG=1
在相应的构建设置部分中定义,则无论发布或调试模式如何,您都将停用代码中的断言。
回答by Todd Lehman
Here's what I do at the top of my main()
:
这是我在我的顶部所做的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
Note that since main()
is a C function and not an Objective-C function, NSCAssert
is used above rather than NSAssert
. (NSAssert
expects self
to be valid.)
请注意,因为main()
是 C 函数而不是 Objective-C 函数,NSCAssert
所以在上面使用而不是NSAssert
. (NSAssert
预计self
有效。)
回答by Dov
Now, as of Xcode 6, the setting is ENABLE_NS_ASSERTIONS
, which is set to 1
for Debug configurations and 0
for Release, by default.
现在,从 Xcode 6 开始,设置为ENABLE_NS_ASSERTIONS
,默认情况下设置为1
用于调试配置和0
用于发布。
You can opt into it for Release builds on the command line by passing the ENABLE_NS_ASSERTIONS=1
argument, which I'm doing for running unit tests that check for assertion conditions, but otherwise should run with the DEBUG
flag off.
您可以通过传递ENABLE_NS_ASSERTIONS=1
参数来选择在命令行上发布版本,我这样做是为了运行检查断言条件的单元测试,否则应该在DEBUG
关闭标志的情况下运行。