Frage

Ich versuche, eine UIAlertView in einem Top-Level-Exception-Handler iPhone angezeigt werden soll. Die Handler-Funktion sieht wie folgt aus:

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

Ich habe an anderer Stelle einen ähnlichen Code zu sehen (zum Beispiel NSSetUncaughtExceptionHandler nicht alle Fehler auf iPhone fangen).

Wenn ich einstufiges im Debugger, kann ich sehen, dass die Exception-Handler aufgerufen wird, und ich kann der aktuelle Bildschirm verdunkeln, als ob es wird die Warnung davor angezeigt werden, aber nichts angezeigt. Außerhalb des Debuggers, die App nur sofort beendet und geht zurück auf das System Home-Bildschirm.

Es funktioniert, wenn ich Fall ein Fehler in applicationDidFinishLaunching und es wird eine Warnung angezeigt vor der Rückkehr. Ich gehe davon aus, dass die Alarmansicht nie eine Chance bekommt in den Exception-Handler angezeigt werden, da die App beendet wird (im Gegensatz zu sitzen, nichts zu tun, wenn ich aus der Patsche helfe nur von applicationDidFinishLaunching). Gibt es eine Möglichkeit, diese Arbeit zu machen?

War es hilfreich?

Lösung

Ich weiß nicht genau, wie [alertView show] implementiert ist, aber ich glaube, es einige Änderungen in der Ansichtshierarchie macht und dann stellt sich die Warnung auf dem nächsten Durchlauf durch die Laufschleife angezeigt werden (aufblicken NSRunLoop).

Aber, da die App im Begriff ist, zu beenden, kehrt Steuerung nicht auf die Laufschleife, so dass der Alarm nie angezeigt wird. Deshalb sollten Sie den Bildschirm dim sehen (die Alarm-Niveau UIWindow wird sofort von show hinzugefügt), aber die Warnung nicht angezeigt (das in der Laufschleife passieren würde).

Wenn Sie [[NSRunLoop currentRunLoop] run] am Ende Ihrer Exception-Handler enthalten, kann die Warnmeldung angezeigt.

Wenn Sie möchten, dass Ihre App lassen beenden, sobald der Alarm erfolgt ist, können Sie wahrscheinlich so tun, indem NSRunLoop der runUntilDate: in einer while-Schleife aufrufen, den Wert eines Flags zu überprüfen, ob die Warnung noch entlassen wurde. Wenn ja, einfach die Handler-Funktion verlassen und Sie sind gut zu gehen. Das bedeutet es eine Delegatobjekt auf dem Alarm der Sätze, dass Flag gesetzt hat.

Wenn Sie Ihre App lassen wollen weiter laufen ... da bin ich nicht so sicher. Sie könnten nur die Laufschleife lassen weiterhin die Exception-Handler laufen, aber es könnten schlecht / seltsame Nebenwirkungen sein, dass. So werden Sie wahrscheinlich sollten wir verlassen die App. Außerdem, wenn Sie sicher sind, können Sie von der Ausnahme wiederherstellen, sollten Sie es irgendwo gefangen haben.

Andere Tipps

Dank Haufen benzado, hier ist was ich denke, ist ein großer generischen Top-Level-Exception-Handler. Ich bin ein Anfänger so hoffentlich es richtig gemacht, aber es funktioniert:)

In meinem ... 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;
}

Und in meinem ... appDelegate.h:

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

Sie sollten überprüfen, ob Code erreicht ist oder wenn Sie gerade Anzeigeproblem haben.

NSLog Wille, dass geklärt werden.

Wenn nicht erreicht, müssen Sie app Herunterfahren verhindern, und Sie können eine verzögerte Wirkung müssen für den Warnruf von diesem Zusammenhang raus:

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

Wenn Sie es erreichen und Ausführungskontext ist kein Problem, aber Sie sind einfach nicht aufmerksam zu sehen, dann [alert zeigen] kann nicht oberster Ebene im Display sein werden. In einem solchen Fall müssen Sie möglicherweise Nachricht über showinview z umleiten mit actionsheet:

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

[actionSheet showInView:topDelegateWindow];
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top