Pregunta

Estoy intentando mostrar UIAlertView en un controlador de excepciones de iPhone de nivel superior.La función del controlador se ve así:

void applicationExceptionHandler(NSException *ex) {
  UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error"
                                                      message:[ex reason]
                                                      delegate:nil
                                             cancelButtonTitle:@"OK"
                                             otherButtonTitles:nil];
  [alertView show];
}

He visto código similar en otros lugares (por ejemplo, NSSetUncaughtExceptionHandler no detecta todos los errores en iPhone).

Si hago un solo paso en el depurador, puedo ver que se llama al controlador de excepciones y puedo ver la pantalla actual atenuada como si fuera a mostrar la alerta delante de ella, pero no aparece nada.Fuera del depurador, la aplicación se cierra inmediatamente y vuelve a la pantalla de inicio del sistema.

Funciona si detecto un error en applicationDidFinishLaunching y muestro una alerta allí antes de regresar.Supongo que la vista de alerta nunca tiene la oportunidad de mostrarse en el controlador de excepciones porque la aplicación está finalizando (en lugar de quedarse ahí sin hacer nada si simplemente salgo de applicationDidFinishLaunching).¿Hay alguna manera de hacer que esto funcione?

¿Fue útil?

Solución

No sé exactamente cómo se implementa [alertView show], pero me imagino que hace algunos cambios en la jerarquía de la vista y luego se pone a ver la alerta en el paso siguiente a través del bucle de ejecución (mirar hacia arriba NSRunLoop).

Pero, puesto que la aplicación está a punto de dejar de fumar, el control no vuelve al bucle de ejecución, por lo que nunca se muestra la alerta. Es por eso que se ve el tenue pantalla (la UIWindow-nivel de alerta se añade inmediatamente por show) pero no aparece la alerta (que sucederían en el bucle de ejecución).

Si se incluye [[NSRunLoop currentRunLoop] run] al final de su manejador de excepciones, puede aparecer la alerta.

Si desea que su aplicación renunció una vez que la alerta se lleva a cabo, es probable que pueda hacerlo llamando runUntilDate: de NSRunLoop en un bucle while, comprobando el valor de una bandera para ver si la alerta se ha descartado todavía. Si es así, simplemente salir de la función de controlador y ya está bueno para ir. Eso significa que usted tiene que fijar un objeto delegado en estado de alerta, que establece que la bandera.

Si desea que su aplicación siguen corriendo ... no estoy tan seguro. Se podía dejar que el bucle de ejecución continúe la marcha del gestor de excepciones, pero puede haber malos efectos secundarios extraños / a eso. Por lo que probablemente debería dejar que la aplicación dejar de fumar. Además, si está seguro de que puede recuperarse de la excepción, que debería haber cogido en alguna parte.

Otros consejos

Gracias montones de benzado, esto es lo que creo que es un gran gestor de excepciones de nivel superior genérico. Soy un principiante así que espero que se hace correctamente, pero funciona:)

En mi ... appDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{        
    [window makeKeyAndVisible];

    NSSetUncaughtExceptionHandler(&exceptionHandler);

    return YES;
}

BOOL exceptionAlertDismissed = FALSE;
void exceptionHandler(NSException *exception)
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"App Committed Suicide"
        message:@"Oh dear, that wasn't supposed to happen. You will have to restart the application... sorry!"
        delegate:[[UIApplication sharedApplication] delegate] cancelButtonTitle:nil otherButtonTitles:@"That's ok!", @"Erm, bye...", nil];
    [alert show];
    [alert release];

    while (exceptionAlertDismissed == FALSE)
    {
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
    }
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    exceptionAlertDismissed = TRUE;
}

Y en mi ... appDelegate.h:

@interface ...appDelegate : NSObject <UIApplicationDelegate, UIAlertViewDelegate>
...
void exceptionHandler(NSException *exception);

Se debe verificar si se alcanza código o si sólo tienen problema de visualización.

NSLog de aclarar que habrá.

Si no se alcanza, es necesario para evitar la desconexión de aplicaciones, y es posible que tenga una acción retardada para salir de ese contexto para la llamada de alerta:

[self performSelector: @selector(showAlert:) withObject:@"msg" afterDelay: 0.1];

Si usted está alcanzando y contexto de ejecución no es un problema, sino que simplemente no está viendo alerta, a continuación, [alerta mostrar] puede que no sea de nivel superior en la pantalla. En tal caso, puede que tenga que redirigir mensaje por ejemplo showinview con actionsheet:

topDelegate=[[UIApplication sharedApplication] delegate];
topDelegateWindow=[topDelegate.window.subviews objectAtIndex:0];

[actionSheet showInView:topDelegateWindow];
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top