9

我正在使用以下代码在我的应用程序中捕获异常:

void uncaughtExceptionHandler(NSException *exception) {
    [FlurryAPI logError:@"Uncaught" message:@"Crash!" exception:exception];
}

只是想知道我是否可以查明发生错误的行号、UIView类等。理想情况下,我希望获得尽可能多的详细信息,因为它是通过FlurryAPI分析捕获的。

FlurryAPI: http ://www.flurry.com/

4

2 回答 2

16

我最终选择了这个:

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];
}

更新(基于@TommyG 下面的评论):

添加NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);到你的 --(BOOL)application:didFinishLaunchingWithOptions:方法的末尾AppDelegate。然后将上述方法也添加到AppDelegate

于 2011-04-02T09:04:21.617 回答
3

您可以利用预编译器并编写一个收集所有值的宏,例如:

#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)

但是,这仅在您抛出异常并从 ObjC 函数内部(self 和_cmd是您在 ObjC 函数中获得的第一个参数,其中 self 是指向类和_cmd选择器的 id 可以是(当前!) 类型转换为 const char)。

但是,如果您只希望 Foundation 异常使用此功能,您有两种选择:

  1. 在 @try() @catch() 块中包装可能引发异常的所有内容,然后引发新的自定义异常
  2. 获取堆栈跟踪,这可能有点困难,因为您的应用程序可能处于不一致的状态并且无法收集所有值。此处详细介绍了收集当前堆栈跟踪。
于 2011-03-31T17:40:21.793 回答