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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 15:56:10  来源:igfitidea点击:

How to know if NSAssert is disabled in release builds?

iosobjective-cxcode

提问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_ASSERTIONSfor your release configuration.

在项目中NS_BLOCK_ASSERTIONS为您的发布配置定义。

Xcode 4 tremplates disable NSAssertsin 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_ASSERTIONSis 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 NSInternalInconsistencyExceptionexception. 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。

enter image description here

在此处输入图片说明

回答by Rob Napier

I will here provide a meta-answer:

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

Both @CocoaFu and @dasblinkenlight are correct. NS_BLOCK_ASSERTIONSturns off NSAssert()and NDEBUGturns 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=1is 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 - <)

enter image description here

在此处输入图片说明

Then observe that the build fails. Therefore NS_BLOCK_ASSERTIONSis defined meaning NSAsserts are disabled.

然后观察构建失败。因此NS_BLOCK_ASSERTIONS,定义意味着NSAsserts 被禁用。

回答by dasblinkenlight

Asserts are conditionally compiled out of your code when NDEBUGis defined. If you define NDEBUG=1in 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, NSCAssertis used above rather than NSAssert. (NSAssertexpects selfto 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 1for Debug configurations and 0for 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=1argument, which I'm doing for running unit tests that check for assertion conditions, but otherwise should run with the DEBUGflag off.

您可以通过传递ENABLE_NS_ASSERTIONS=1参数来选择在命令行上发布版本,我这样做是为了运行检查断言条件的单元测试,否则应该在DEBUG关闭标志的情况下运行。