问题
I have a method that has several parts that can throw an exception. If one of these parts fail, I would like the cleaning method to run. I am thinking about using the try/catch directive.
My question is: will I have to use one directive for every line of code that can throw an exception or can I simply include the whole method in a block like this?
@try {
[self doStuff];
// doStuff has several passages that could throw an exception
}
@catch (NSException * e) {
[self cleanTheWholeThing];
}
In this case it is not important to me which line generated the problem. I just need the method to run successfully or do other stuff in case it fails.
thanks
回答1:
You can certainly have multiple lines in your try block. Example:
@try {
if (managedObjectContext == nil) {
actionMessage = @"accessing user recipe library";
[self initCoreDataStack];
}
actionMessage = @"finding recipes";
recipes = [self recipesMatchingSearchParameters];
actionMessage = @"generating recipe summaries";
summaries = [self summariesFromRecipes:recipes];
}
@catch (NSException *exception) {
NSMutableDictionary *errorDict = [NSMutableDictionary dictionary];
[errorDict setObject:[NSString stringWithFormat:@"Error %@: %@", actionMessage, [exception reason]] forKey:OSAScriptErrorMessage];
[errorDict setObject:[NSNumber numberWithInt:errOSAGeneralError] forKey:OSAScriptErrorNumber];
*errorInfo = errorDict;
return input;
} @catch (OtherException * e) {
....
} @finally {
// Any clean up can happen here.
// Finally will be called if an exception is thrown or not.
}
And a link to practical use of exceptions:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Exceptions/Tasks/HandlingExceptions.html
回答2:
If you can, avoid exceptions. Even Apple recommends to avoid them:
Instead of exceptions, error objects (NSError) and the Cocoa error-delivery mechanism are the recommended way to communicate expected errors in Cocoa applications.
See also their Error Handling Programming Guide (it's marked as being Mac related but is equally valid for iPhone, the same concepts apply).
The reasons for avoiding exceptions are that I know of are:
- They are slower than reporting via NSError and an out-pointer.
- They can result in memory leaks if you aren't very careful. Some memory leaks due to exceptions cannot be avoided at all (in non-GC environments).
- You might forget to catch them, and then your app crashes.
In general, exceptions in Objective-C are used for really exceptional problems that are often unrecoverable. They are almost never used in area where you expect something can go wrong (like network communication; the NSURLConnection
methods do not throw exceptions for this reason but export an NSError
). This may be different from other languages where exceptions are used more often. In the projects I've been working on I had only once the need to catch and handle an exception (can't remember which, though).
Instead, you should do something like this:
// Returns YES when successful.
- (BOOL)doSomething:(NSError **)outError
{
// ...
if (someErrorOccurred) {
if (outError) {
outError = [NSError
errorWithDomain:@"MyErrorDomain"
code:123
userInfo:nil
];
// Or maybe even use your own NSError subclass
return NO;
}
}
// ...
// Operation was successful.
return YES;
}
回答3:
Its completely alright to enclose the method call with try-catch block.
回答4:
If you don't care which line caused the exception you can enclose the entire function in a try/catch block.
For example, assume that f1(), f2() or f3() can throw an exception in this code:
try {
f1();
f2();
f3();
}
catch( ... ) {
...either f1, f2 or f3 threw an exception - don't know which
}
回答5:
You can include the whole method body in your try
block.
In your catch
part you can have multiple catch
blocks to handle different types of exceptions:
@catch (NSException * e) {
....
}
@catch (OtherException * e) {
....
}
@finally {
NSLog(@"finally");
}
so you could also discern exactly which line failed based on the specific exception raised, if you ever need it.
回答6:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Exceptions/Tasks/HandlingExceptions.html You can include the whole method body in your try block.
来源:https://stackoverflow.com/questions/6477416/iphone-try-catch-question