views:

617

answers:

1

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.

+1  A: 

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
This is what NSAssert does by default -- it raises an NSInternalInconsistencyException. So you're advocating the catch/re-raise solution above?
Sickpea
I have re-read the documentation and NSAssert does raise an exception. So your current solution seems right.
Laurent Etiemble