How to Know If Nsassert Is Disabled in Release Builds

How to know if NSAssert is disabled in release builds?

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.

NSAssert(boolean) in release

As long as the expression which results in a does not have side-effects, why not put it directly into NSAssert? E.g.

NSAssert(<expr>, @"...")

Note that if <expr> has side-effects, e.g. prints something, this may not happen in non-Debug builds.

Does the NS_BLOCK_ASSERTIONS disable both NSAssert and assert() calls?

No, assert() is controlled with the NDEBUG symbol:

#ifdef NDEBUG
#define assert(e) ((void)0)
#else
...

(see /usr/include/assert.h if you have the Xcode Command Line Tools installed, or elsewhere in the Xcode.app bundle, if not).

What's the point of NSAssert, actually?

Assert is to make sure a value is what its supposed to be. If an assertion fails that means something went wrong and so the app quits. One reason to use assert would be if you have some function that will not behave or will create very bad side effects if one of the parameters passed to it is not exactly some value (or a range of values) you can put an assert to make sure that value is what you expect it to be, and if it's not then something is really wrong, and so the app quits. Assert can be very useful for debugging/unit testing, and also when you provide frameworks to stop the users from doing "evil" things.

NS_BLOCK_ASSERTIONS in Objective-C

If you created your Xcode project based on one of the standard templates, the Cocoa headers (including NSException.h which contains the NSAssert macros) will get preprocessed before any other files in the project. A #define NS_BLOCK_ASSERTIONS in any of the project's header or implementation files therefore has no effect on the NSAssert macros.

Try putting NS_BLOCK_ASSERTIONS into the preprocessor macros of your target or even project (for the release configuration only):

GCC_PREPROCESSOR_DEFINITIONS = NS_BLOCK_ASSERTIONS

Or put #define NS_BLOCK_ASSERTIONS into the prefix (.pch) header before the #import <Cocoa/Cocoa.h> or #import <Foundation/Foundation.h> lines.

NSAssert(boolean) in release

As long as the expression which results in a does not have side-effects, why not put it directly into NSAssert? E.g.

NSAssert(<expr>, @"...")

Note that if <expr> has side-effects, e.g. prints something, this may not happen in non-Debug builds.

Disable assertions while testing

Solved, I added a new configuration, duplicated from Debug, called Test.

Sample Image

Then added NS_BLOCK_ASSERTIONS=1 in the build settings preprocessor macros.

Sample Image

Finally, change the test action in the test's scheme.

Sample Image

Now it works :)

ios NSAssert analog for normal build?

You are right. Xcode automatically turns off assertions for release builds. If you really want to have them in your release build you can remove the -DNS_BLOCK_ASSERTIONS=1 flag from Other C / C++ flags in your build settings.



Related Topics



Leave a reply



Submit