2012-02-29 20 views
7

En MonoTouch, ¿Cómo registro un controlador no detectada excepción (o una función similar)MonoTouch: uncaughtExceptionHandler?

En Obj-C:

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

- (void)applicationDidFinishLaunching:(UIApplication *)application { 
    NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler); 
    [FlurryAnalytics startSession:@" "]; 
    .... 
} 

Respuesta

-4

se agrega un controlador de try-catch alrededor del código que (podría) throw NSExceptions :

try { 
    FlurryAnalytics.StartSession (" "); 
} catch (MonoTouchException ex) { 
    Console.WriteLine ("Could not start flurry analytics: {0}", ex.Message); 
} 

MonoTouch ya se instala un controlador de excepciones, y traduce automáticamente las excepciones a las excepciones objectivec gestionados.

+2

Esto realmente no responde a su pregunta original. –

1
public delegate void NSUncaughtExceptionHandler(IntPtr exception); 

    [DllImport("/System/Library/Frameworks/Foundation.framework/Foundation")] 
    private static extern void NSSetUncaughtExceptionHandler(IntPtr handler); 

    // This is the main entry point of the application. 
    private static void Main(string[] args) 
    { 
      NSSetUncaughtExceptionHandler(
       Marshal.GetFunctionPointerForDelegate(new NSUncaughtExceptionHandler(MyUncaughtExceptionHandler))); 

      ... 
    } 

    [MonoPInvokeCallback(typeof(NSUncaughtExceptionHandler))] 
    private static void MyUncaughtExceptionHandler(IntPtr exception) 
    { 
     var e = new NSException(exception); 
     ... 
    } 
+0

¡Impresionante, gracias! Lo único es que el constructor de NSException que toma un IntPtr está protegido, por lo que debe subtipificarlo y exponer esa versión del constructor. De lo contrario, esto fue súper útil. –

+0

[Aquí] (http://stackoverflow.com/questions/37525472/create-nsexception-from-intptr/37527174#37527174) puede ver cómo 'NSException' acepta un' IntPtr' como argumento. – testing

0

Esto hace el trabajo. Llame al método SetupExceptionHandling() en el inicio de la aplicación. La magia es la parte NSRunLoop. Pero la aplicación va a estar en un estado extraño en ese punto, con efectos impredecibles. Por lo tanto, sugiero que se elimine la aplicación una vez que el usuario decida qué hacer con la excepción, por ejemplo, volviéndola a lanzar.

public static class IOSStartupTasks { 
    private static bool _HaveHandledException; 
    public static void HandleException(object sender, UnhandledExceptionEventArgs e) { 
    if (!(_HaveHandledException)) { 
     _HaveHandledException = true; 
     UIAlertView alert = new UIAlertView("Error", "Bad news", "report", "just crash"); 
     alert.Delegate = whatever; // delegate object should take the exception as an argument and rethrow when it's done handling user input. 
     alert.Show(); 
     NSRunLoop.Current.RunUntil(NSDate.DistantFuture); // keeps the app alive, but likely with weird effects, so make sure you don't let the user back into the main app. 
    } 
    } 

    public static void SetupExceptionHandling() { 
    AppDomain domain = AppDomain.CurrentDomain; 
    domain.UnhandledException += (object sender, UnhandledExceptionEventArgs e) => 
     IOSStartupTasks.HandleException(sender, e); 
    } 
}