5

I'm trying to use NSAssert throughout my iPhone app so that if an unexpected condition occurs, the application fails-fast and crashes with a meaningful message in the crash log.

This works fine if the failing NSAssert is on the main thread, as it raises NSInternalInconsistencyException by default which is uncaught and stops execution. But I'm also doing processing in background threads, in which case the NSAssert just aborts the thread, but the programming keeps running.

My current solution is to catch and rethrow the exception in the main thread (in this case, NSOperation's main method):

- (void)main {
    @try {
        int x = 14;
        ...
        NSAssert1(x > 20, @"x should be greater than 20, was %d", x);
        ...
    }
    @catch (NSException *e) {
        [e performSelectorOnMainThread:@selector(raise) withObject:nil waitUntilDone:YES];
    }
}

Is there a better way? Perhaps using a custom NSAssertionHandler?

I know I could just use C's assert with a static annotation:

assert(x > 20 && "x should be greater than 20");

But this doesn't allow me to show what the actual failing value of x is.

Trashpanda
  • 14,758
  • 3
  • 29
  • 18
  • I'm having the same problem, but the proposed solution won't work for me. The NSAssert is being triggered, the thread dies, but the app continues running. I'm using the Cocos2D engine. Could anybody provide a more complete solution? – Ricardo Sanchez-Saez Jun 08 '11 at 15:51

1 Answers1

1

You can replace the NSAssert with a test code followed by an exception raise. This way, if the assertion failed, an exception will be thrown, catched by the @catch block and re-raised on the main thread.

Note: You can even define a C macro, in order to provide a compact form.

Laurent Etiemble
  • 27,111
  • 5
  • 56
  • 81
  • This is what NSAssert does by default -- it raises an NSInternalInconsistencyException. So you're advocating the catch/re-raise solution above? – Trashpanda Jan 17 '10 at 00:42
  • I have re-read the documentation and NSAssert does raise an exception. So your current solution seems right. – Laurent Etiemble Jan 17 '10 at 15:41