2011-03-31 7 views
9

estoy usando el siguiente código para capturar excepciones en mi aplicación:Objective-C/iPhone - NSException capturar la mayor cantidad de información posible

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

preguntaba si puedo punta de alfiler, números de línea, UIView , clases, etc. que el error está ocurriendo. Idealmente, me gustaría obtener toda la información detallada que pueda obtener, ya que está capturada por el análisis FlurryAPI.

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

Respuesta

16

Terminé yendo con esto:

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

ACTUALIZACIÓN (basado en comentario de @ TommyG abajo):

Añadir NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler); hasta el final de su - -(BOOL)application:didFinishLaunchingWithOptions: método en el AppDelegate. A continuación, agregue el método anterior al AppDelegate también.

+1

¿dónde colocas este método? ¿está en el delegado de la aplicación? Aparece una advertencia que indica que no hay un prototipo anterior para este método. – TommyG

+1

@TommyG Agregue 'NSSetUncaughtExceptionHandler (& uncaughtExceptionHandler);' al final de su aplicación '- (BOOL): didFinishLaunchingWithOptions:' en AppDelegate. A continuación, agregue el método anterior a AppDelegate también. – alex

+1

¿Esto realmente le da un rastro de pila? – jjxtra

3

Usted puede hacer que las ventajas de la precompilador y escribir una macro que reúne todos los valores, por ejemplo:

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

Sin embargo, esto sólo funciona cuando se lanza una excepción y desde dentro de una función ObjC (self y _cmd son los primeros parámetros que obtienes en una función ObjC, donde self es una identificación que apunta a la clase y _cmd al selector que puede estar (actualmente!) encasillado en const char).

Sin embargo, si desea que esta sólo para excepciones de la Fundación, tiene dos opciones:

  1. Wrap todo lo que podría lanzar una excepción en @try() @catch() bloques y luego lanzar una nueva, la costumbre , excepción
  2. Obtener el seguimiento de pila, esto es lo que podría ser un poco más difícil ya que su aplicación es posible en un estado incoherente y no puede reunir todos los valores. La recopilación de la traza actual de la pila está cubierta con gran detalle en here.
+0

Veo, ¿estaría definiendo esas macros dentro de AppDelegate? Si es así, ¿cómo voy a usarlos dentro de mi void uncaughtExceptionHandler (excepción NSException *)? – fuzz

+1

@Fulvio Cusumano: Ah, bueno, el macro no está destinado a ser utilizado en su controlador, ya que es muy tarde en este momento para obtener los valores necesarios del precompilador, pero debe usarse para crear excepciones y luego lanzarlas . Como dije, si solo necesita excepciones de Foundations, puede usar @try() y @catch() para crear nuevas excepciones o bajar la pila. – JustSid

Cuestiones relacionadas