EDIT: Issue has been solved(partially):It is a simulator bug. I've compiled and tested this on two devices with iOS 3.1.3 and 4.0. The exception was handled correctly. Be careful, the simulator is your enemy!
this is driving me crazy. I don't know how to enable exception handling in my project. Look at the code and debugger output below.
My Goal is to catch the exception, not correcting the code so the exception is handled and the app doesn't crash.
I'm using XCode 3.2.3, iPhone SDK 4 final. I have just created a simple view based iPhone App to test thi开发者_StackOverflow社区s.
I have looked in my project settings and yes the switch "Enable Objective-C Exceptions" is checked. I am using GCC 4.2.
When I look at the build process in detail the compiler flag -fno-objc-exceptions is not within the list of arguments!
What am I missing here?
Thanks in advance Nick
NSArray * foo = [[NSArray alloc] init];
@try {
NSLog(@"trying...");
[foo objectForKey:@"yeah"];
}
@catch (NSException * e) {
NSLog(@"catching %@ reason %@", [e name], [e reason]);
}
@finally {
NSLog(@"finally");
}
leads to
trying...
-[__NSArrayI objectForKey:]: unrecognized selector sent to instance 0x5d5f780
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI objectForKey:]: unrecognized selector sent to instance 0x5d5f780'
*** Call stack at first throw:
(
0 CoreFoundation 0x02393919 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x024e15de objc_exception_throw + 47
2 CoreFoundation 0x0239542b -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x02305116 ___forwarding___ + 966
4 CoreFoundation 0x02304cd2 _CF_forwarding_prep_0 + 50
...
)
terminate called after throwing an instance of 'NSException'
Whether the catch nor the finally block is ever reached.
Quote from How do I catch global exceptions? :
"objc_exception_throw
is not an exception. It is the function that throws Objective-C exceptions. Similarly, EXC_ARITHMETIC
is not an Objective-C exception; it is a Mach (kernel) exception, meaning that your app tried to do something completely invalid. – Peter Hosey May 14 at 9:14"
That thread does have a link to a solution for your problem though, it appears. The link goes to http://www.restoroot.com/Blog/2008/10/20/crash-reporter-for-iphone-applications-part-2/ which looks a little risky, but if it works, it might be worth it for you.
There are bug reports related to this, e.g.: http://www.openradar.me/8081169 (posted earlier this month)
(Updated to summarize information from comments below.)
If I understand your problem right.
Your Try/ catch block is working correctly.
It is trying to run your code, and catches an error. You need to decide what to do when it catches an error and code for it within the block. I normally do that in the CATCH part. As the finally bit will execute regardless of an exception or not being thrown.
Your example code is catching the NSException
exception but not the one being thrown, NSInvalidArgumentException
. You might have better luck if you look for that specific exception.
NSArray * foo = [[NSArray alloc] init];
@try {
NSLog(@"trying...");
[foo objectForKey:@"yeah"];
}
@catch (NSInvalidArgumentException *e) {
NSLog(@"Invalid argument called.");
}
@catch (NSException * e) {
NSLog(@"catching %@ reason %@", [e name], [e reason]);
}
@finally {
NSLog(@"finally");
}
I don't have any way of testing it myself right now, though.
See http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocExceptionHandling.html for more information.
精彩评论