的Objective-C/iPhone - NSException获取尽可能多的信息可能

问题描述:

我使用下面的代码以捕捉我的应用程序异常:的Objective-C/iPhone - NSException获取尽可能多的信息可能

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

只是想知道我是否能够针点,行号,UIView ,类,等错误的发生。理想情况下,我希望获得尽可能详细的信息,因为它被FlurryAPI分析捕获。

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

我结束了这是怎么回事:

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(基于以下@ TommyG的评论):

添加NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);到您的结束 - -(BOOL)application:didFinishLaunchingWithOptions:方法AppDelegate。然后将上述方法添加到AppDelegate

+1

你在哪里放置这个方法?它在应用程序委托中吗? – TommyG 2012-03-19 21:12:02

+1

@TommyG将'NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler)'添加到AppDelegate中' - (BOOL)应用程序的末尾:didFinishLaunchingWithOptions:'方法。然后将上述方法添加到AppDelegate。 – alex 2012-07-30 07:32:27

+1

这实际上是否给你一个堆栈跟踪? – jjxtra 2012-10-06 01:38:54

您可以预编译的优势,编写一个宏收集所有的值,例如:

#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是指向类的id,而_cmd指向可以(当前!)类型化为const char的选择器)。

但是,如果你想这仅适用于基金例外,你有两个选择:

  1. 可能在@try()@catch抛出一个异常()块,然后抛出一个新的自定义裹一切,例外
  2. 获取堆栈跟踪,这可能会更难一点,因为您的应用可能处于不一致的状态,并且无法收集所有值。收集当前堆栈跟踪非常详细,涵盖here
+0

我明白了,我会在AppDelegate中定义这些宏吗?如果是这样,那么我将如何在我的void uncaughtExceptionHandler(NSException * exception)中使用它们? – fuzz 2011-04-02 04:00:59

+1

@Fulvio Cusumano:好的,这个宏并不意味着要在你的处理程序中使用,因为现在已经迟到了从预编译程序获取所需的值,但应该用它来创建异常,然后将它们扔出去。就像我所说的,如果你只需要Foundations异常,你可以使用@try()和@catch()来创建一个新的异常,或者沿着堆栈走下去。 – JustSid 2011-04-02 07:56:47