Catching Exceptions via NSInvocation and NSProxy Is No Longer Possible in Objective C

This issue has already been raised in several places, but in the hopes of adding some more visibility to the issue I figured it would not hurt to post it here. Under the iOS 3.2 and iOS 4 simulator platforms it is no longer possible to catch exceptions via NSInvocation and Apple’s object proxy mechanism (NSProxy). Specifically, it makes it almost impossible to use OCHamcrest and OCMock as they both rely heavily on dynamic invocation and proxy objects.

The issue has already been raised here:

I created a sandbox project in an attempt to diagnose the various scenarios in which exception handling did not work. Until Apple releases a fix for the bug it is going to take some creative work-arounds in order to “move on” from the issue.

It is still possible to catch exceptions via an NSInvocation if you fallback to using the objc_msgSend function in lieu of [invocation invoke]. OCHamcrest and OCMock could be patched to temporarily use that workaround until Apple releases a fix. The Google Toolbox guys have already rolled this workaround into their test runner.

For example,

Uncatchable Implementation

Workaround

This will get around the NSInvocation issue (for the most part), but throwing exceptions within an NSProxy object is still broken. The only workaround I can envision would be to use objc_exception_throw; which appears to be undocumented. It is anyone’s guess if that will work around the issue. But it might be worth a try.

Conversation
  • Ben says:

    You’re just calling the object directly; the NSInvocation isn’t doing a thing in this case.

  • Justin DeWind Justin DeWind says:

    Correct,

    You could simply do objc_msgSend(obj, @selector(method)).

  • Comments are closed.