Sometimes the argument is from performance. I can buy that.
But the most frequent argument I see is basically, "maybe it'll still work." Basically, it's rude to crash the app on purpose and lose the user's work when maybe, maybe, if you keep on going from an assertion failure the program will still work somehow.
Sure. And maybe you'll crash strangely. And maybe you'll corrupt the user's data, ruining all of their work, not just whatever you didn't save.
What really drives me nuts is that, on the Mac, Apple codifies this crazy idea. The NSAssert macro throws an exception on failure, and uncaught exceptions on the main thread get caught by a handler in the event loop which logs the exception and continues running the app!
There's a defaults setting you can use that will pop up a window with crash/continue options if it catches your NSException.
But it is inconsistent - some old stuff like NSInvocation also catches and throws out exceptions, but dispatch queues will kill your process if they catch one.
Even if you could modify the behavior, having the default work this way would still be terrible.
edit: Also I'm not suggesting to just naively exit(1).
edit2: Strangely, exception generating code in [[NSOperationQueue mainQueue] addOperationWithBlock:] does actually hit the NSUncaughtExceptionHandler, which was surprising to me.
Good call about reportException:. Although I personally prefer to just avoid NSAssert. The good old C assert() gets the job done well for me.
One could certainly argue that making nil messaging an error is better, but either way it's a different sort of reasoning.
It's a great language feature I appreciated in Obj-C, and not lost to Swift!