Perhaps I was missing some subtlety (though my skimming of NSException.h seems to bear me out), but my thinking is that #defining NS_BLOCK_ASSERTIONS gives NSAssert() no effect:
#if !defined(NS_BLOCK_ASSERTIONS)
...
#else // NS_BLOCK_ASSERTIONS defined
#if !defined(_NSAssertBody)
#define NSAssert(condition, desc, ...) do {} while (0)
#endif
...
#endif
… so if your code relies on Clang understanding that the function will exit early upon the failure of the assertion, your reliance would be misplaced. Nothing would remain to tell it so. To silence Clang, you have to provide a code path that returns as the function declaration promises.
You make the excellent point that maybe code shouldn't get into that position — you should leave the assertions in, or otherwise test and handle the exceptional condition in every case. "Assertions encapsulate the fail branch" was an incredibly awkward way to put it, though.
— F