47

I often saw "assert " in iOS code, I google it, and got to know it assert true or false.

I want to know if this will auto disable in release mode?

DuckMaestro
  • 15,232
  • 11
  • 67
  • 85
qichunren
  • 4,405
  • 7
  • 37
  • 48
  • 3
    It is, frankly, a crazy design that asserts aren't turned off in release builds by default. Flies in the face of every other C compiler I know of. – Seva Alekseyev Mar 09 '12 at 16:21
  • 2
    @SevaAlekseyev Agree, we got a shock when Assertions still came through in Release. Completely unconventional. Our philosophy is 'fail fast in development, die hard in production'. – Chris Hatton Oct 06 '15 at 06:50

7 Answers7

51

Update: Verified this works in Xcode 8 as well.

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".

I have successfully enabled/disabled NSAssert from there.

enter image description here

Jeff
  • 3,829
  • 1
  • 31
  • 49
47

Use NSAssert() and its companions.

in the project define NS_BLOCK_ASSERTIONS for your release configuration.

Xcode 4 tremplates disable NSAsserts in the release configuration. It adds

-DNS_BLOCK_ASSERTIONS=1

to "Other C Flags" for "Release".

From the documentation:

Assertions are disabled if the preprocessor macro NS_BLOCK_ASSERTIONS is defined.

The NSAssert macro evaluates the condition and serves as a front end to the assertion handler.

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.

This macro should be used only within Objective-C methods.

djromero
  • 19,551
  • 4
  • 71
  • 68
zaph
  • 111,848
  • 21
  • 189
  • 228
35

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.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
8

As Zaph said -DNS_BLOCK_ASSERTIONS=1 is set for release. However, if you wanted to check this.

First observe in the docs that NSAssert is disabled by the macro NS_BLOCK_ASSERTIONS. Then add this to the build and observe it complies ok:

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

Then change the scheme to release (cmd - shift - <)

enter image description here

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

Robert
  • 37,670
  • 37
  • 171
  • 213
5

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.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
3

Here's what I do at the top of my 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.)

Todd Lehman
  • 2,880
  • 1
  • 26
  • 32
1

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.

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.

Dov
  • 15,530
  • 13
  • 76
  • 177