Objective-C / iPhone - NSexception Painting как можно больше информации
-
14-11-2019 - |
Вопрос
Я использую следующий код для захвата исключений в моем приложении:
void uncaughtExceptionHandler(NSException *exception) {
[FlurryAPI logError:@"Uncaught" message:@"Crash!" exception:exception];
}
.
Просто задаваясь вопросом, могу ли я пин-точку, номера строк, UIView
, классы и т. Д., чтобы ошибка возникала.В идеале я бы хотел, чтобы столько подробную информацию, поскольку я могу получить, так как он захвачен аналитикой FlurryAPI
.
Flurryapi: http://www.flurry.com/
Решение
I ended up going with this:
void uncaughtExceptionHandler(NSException *exception) {
NSArray *backtrace = [exception callStackSymbols];
NSString *platform = [[UIDevice currentDevice] platform];
NSString *version = [[UIDevice currentDevice] systemVersion];
NSString *message = [NSString stringWithFormat:@"Device: %@. OS: %@. Backtrace:\n%@",
platform,
version,
backtrace];
[FlurryAPI logError:@"Uncaught" message:message exception:exception];
}
UPDATE (based on @TommyG's comment below):
Add NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
to the end of your - -(BOOL)application:didFinishLaunchingWithOptions:
method in AppDelegate
. Then add the above method to the AppDelegate
as well.
Другие советы
You can make advantage of the precompiler and write a macro which gathers all the values, eg:
#define __ThrowException(name, reason, class, function, file, line, info) [NSException exceptionWithName:name reason:[NSString stringWithFormat:@"%s:%i (%@:%s) %@", file, line, class, function, reason] userInfo:info];
#define ThrowException(name, reason, info) __ThrowException(name, reason, [self class], _cmd, __FILE__, __LINE__, info)
However, this only works when you throw an exception and from inside an ObjC function (self and _cmd
are the very first parameters you get in an ObjC function, where self is an id which points to the class and _cmd
to the selector which can be (currently!) typecasted to const char).
However, if you want this only for Foundation exceptions, you have two options:
- Wrap everything that might throw an exception in @try() @catch() blocks and then throw a new, custom, exception
- Get the stack trace, this is what might be a little more hard as your app is possible in an inconsistent state and can't gather all the values. Gathering the current stack trace is covered here in great detail.