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.


I can't really speak to NSAssert, but I imagine that it works similarly to C's assert().

assert() is used to enforce a semantic contract in your code. What does that mean, you ask?

Well, it's like you said: if you have a function that should never receive a -1, you can have assert() enforce that:

void gimme_positive_ints(int i) {
  assert(i > 0);
}

And now you'll see something like this in the error log (or STDERR):

Assertion i > 0 failed: file example.c, line 2

So not only does it safe-guard against potentially bad inputs but it logs them in a useful, standard way.

Oh, and at least in C assert() was a macro, so you could redefine assert() as a no-op in your release code. I don't know if that's the case with NSAssert (or even assert() any more), but it was pretty useful to compile out those checks.


NSAssert gives you more than just crashing the app. It tells you the class, method, and the line where the assertion occurred. All the assertions can also be easily deactivated using NS_BLOCK_ASSERTIONS. Thus making it more suitable for debugging. On the other hand, throwing an NSException only crashes the app. It also does not tell about the location of the exception, nor can it be disabled so simply. See the difference in the images below.

The app crashes because an assertion also raises an exception, as the NSAssert documentation states:

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.

NSAssert:

Logs after an assertion

NSException:

Logs after an exception


Apart from what everyone said above, the default behaviour of NSAssert() (unlike C’s assert()) is to throw an exception, which you can catch and handle. For instance, Xcode does this.