Exceptions raised from an NSInvocation cannot be caught

Number:rdar://8237699 Date Originated:26/07/2010
Status:Duplicate/8033271 Resolved:
Product:iOS SDK Product Version:4.0
Classification:Serious Bug Reproducible:Always
When a selector invoked (either directly or indirectly) using an NSInvocation raises an exception, it cannot be caught with a @try/@catch block when using the iOS Simulator SDK. The problem does not occur using the device SDK.

Steps to Reproduce:

The simplest case is to create an invocation for a given selector inside an object, then invoke it on self. Implement that selector to raise an exception and try and catch it.

- (NSInvocation *)getInvocationForSelector:(SEL)aSelector;
  // create and return the invocation here

- (void)doSomething;
  [[NSException exceptionWithName:@"Testing" reason:nil userInfo:nil] raise];

- (void)testTheBug;
  @try {
    NSInvocation *invocation = [self getInvocationForSelector:@selector(doSomething)];
    [invocation invokeWithTarget:self];
  @catch (NSException *e) {
    // should jump to here, but it does not

Expected Results:
The exception raised in doSomething should be caught in testTheBug;

Actual Results:
With the device SDK, the exception is caught. With the simulator SDK, it is not and an uncaught exception is thrown and a crash results.

According to this similar bug report: rdar://8081169 this did not occur in SDKs prior to 3.2.

This technique is used by various testing tools such as Google Toolbox for Mac and OCMock. I am also working on a mock object library that uses this pattern to allow mocks to throw exceptions when an expected or stubbed method is called. This bug makes it hard to uses these tools properly against the simulator SDK.


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!