Frage

Einer meiner Freunde hat mich gebeten, nicht NSException in iPhone Apps zu verwenden. Der Grund nannte er „Performance-Engpass“. Aber ich bin nicht überzeugt davon.

Kann jemand bestätigen mir, dass wir von der Verwendung NSException in iPhone App zurückhalten sollte? Wenn Sie für den Umgang mit NSException haben, geben Sie bitte das auch.

UPDATE:

Das link Anfragen uns Ausnahmebehandlung bei der App-Ebene zu verwenden. Hat jemand jemals getan? Bitte geben Sie die Vorteile davon und andere Leistung hitches könnte es schaffen.

War es hilfreich?

Lösung

Kurz gesagt:

Keine Ausnahmen verwenden, um alles andere als nicht behebbare Fehler

zeigen

Es ist nur zur Anwendung eines geeigneten @ versuchen / @ Fang mit nicht behebbaren Fehlern zu behandeln. Es wird nie zur Anwendung einer geeigneten @ werfen / @ try / catch @ Steuerfluss wie Operationen auf iOS oder Mac OS X dann auch zu tun, sorgfältig zu prüfen, ob Sie besser gestellt sind, eine Ausnahme unter Verwendung eines nicht behebbaren Fehler anzuzeigen oder einfach abstürzt ( nennen abort ()); ein Absturz oft hinter Blättern deutlich mehr Beweise.

Zum Beispiel wäre es nicht angebracht, zu verwenden, für den Fang von Out-of-bounds Ausnahmen, es sei denn, Ihr Ziel ist sie zu fangen und irgendwie die Fehler melden, dann - in der Regel - Absturz oder zumindest die Benutzer warnen dass Ihre Anwendung in einem inkonsistenten Zustand und kann Daten verloren gehen.

Verhalten von jedem durch das System Framework-Code ausgelöste Ausnahme ist nicht definiert.


  

Können Sie das „Verhalten von jedem erklären   Ausnahme durch das System geworfen   Framework-Code ist nicht definiert.“in   Detail aus?

Klar.

Das System Frameworks verwenden, um ein Design, bei dem jede Ausnahme gilt als tödlich, nicht erstattungs, Fehler zu sein; ein Programmierer Fehler, für alle Absichten und Zwecke. Es gibt eine sehr begrenzte Anzahl von Ausnahmen (heh) von dieser Regel.

Damit bei der Umsetzung, der Systemrahmen wird nicht dafür sorgen, dass alles unbedingt richtig gereinigt, wenn eine Ausnahme, dass durchläuft System Framework-Code geworfen wird. Sine die Ausnahme ist per definitionem nicht behebbar, warum die Kosten für die Bereinigung bezahlen?

Betrachten Sie diesen Call-Stack:

your-code-1()
    system-code()
        your-code-2()

d. Code, in dem Sie den Code Anrufe in dem Systemcode, der in mehr Ihrem Code aufruft (ein sehr häufiges Muster, obwohl das Call-Stacks offenbar deutlich tiefer ist).

Wenn your-code-2 eine Ausnahme auslöst, dass die Ausnahmen über system-code geht, bedeutet das Verhalten nicht definiert ist; system-code kann oder auch nicht lassen Sie Ihre Anwendung in einem undefinierten, potentiell crashy oder datenverlustbehaftete, Zustand.

Oder stärker. Sie können nicht eine Ausnahme in your-code-2 mit der Erwartung werfen, dass Sie fangen können und es in your-code-1 Griff

Andere Tipps

Ich habe gebrauchte Ausnahmebehandlung für meinen ziemlich intensiven Audio-App ohne Probleme überhaupt. Nach viel Lesen und ein wenig Benchmarking und Demontage Analyse kam ich bin zu dem umstrittenen Schluss, dass es keinen wirklichen Grund, sie nicht zu verwenden (intelligent) und viel Grund, nicht zu (NSError Zeiger-Zeiger, endlose conditionals ... igitt!). Die meisten, was die Leute in den Foren sagen, wiederholt nur das Apple-Docs.

Ich gehe in ein ziemlich viel Detail in dieses Blog-Post aber ich werde meine Ergebnisse hier skizzieren:

Mythos 1: @ try / @ catch / @ schließlich zu teuer ist (in Bezug auf CPU)

Auf meinem iPhone 4, das Werfen und Fangen 1 Million Ausnahmen dauert etwa 8,5 Sekunden. Dies entspricht etwa nur 8,5 Mikrosekunden für jeden. Teure in Ihrem Realtime Core Audio-Thread? Vielleicht ein bisschen (aber Sie würden nie Ausnahmen werfen dort würden Sie ??), aber ein 8.5µs Verzögerung in der UIAlert der Benutzer sagen, ein Problem beim Öffnen ihrer Datei dort war, wird es bemerkt zu gehen?

Mythos 2: @try Blöcke eine Kosten auf 32-Bit-iOS

Der Apple-docs spricht von "Zero-Cost-@try Blöcken auf 64bit " und erklärt, dass 32-Bit eineine Kosten entstehen. Ein wenig Benchmarking und Demontage Analyse scheint darauf hinzudeuten, dass es Null-Kosten @try Blöcke auf 32-Bit-iOS (ARM-Prozessor) als auch. Hat Apple-bedeuten 32bit sagen Intel

Mythos 3: es wichtig ist, dass durch Cocoa Frameworks Geworfen Ausnahmen sind nicht definiert

Ja, sie sind „nicht definiert“, aber was tun Sie sowieso über den Apple Rahmen zu werfen? Natürlich von Apple nicht verarbeitet sie für Sie. Der vollständige Punkt Ausnahme der Implementierung für behebbare Fehler Handhabung ist dieses vor Ort zu behandeln -. Nur nicht jeden-einzeiligen „vor Ort“

Ein Grenzfall ist hier mit Methoden wie NSObject:performSelectorOnMainThread:waitUntilDone:. Wenn der spätere Parameter JA ist, wirkt dies wie eine synchrone Funktion in dem Fall, dass Sie die Ausnahme Blase vergeben werden könnten, um Ihre Berufung Spielraum für erwarten. Zum Beispiel:

/////////////////////////////////////////////////////////////////////////
#pragma mark - l5CCThread
/////////////////////////////////////////////////////////////////////////

@interface l5CCThread : NSThread @end

@implementation l5CCThread

- (void)main
{
    @try {

        [self performSelectorOnMainThread:@selector(_throwsAnException) withObject:nil waitUntilDone:YES];

    } @catch (NSException *e) {
        NSLog(@"Exception caught!");
    }
}
- (void)_throwsAnException { @throw [NSException exceptionWithName:@"Exception" reason:@"" userInfo:nil]; }

@end

/////////////////////////////////////////////////////////////////////////
#pragma mark - l5CCAppDelegate
/////////////////////////////////////////////////////////////////////////

@implementation l5CCAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    l5CCThread *thd = [[l5CCThread alloc] init];
    [thd start];

    return YES;
}
// ...

In diesem Fall wird die Ausnahme wäre „durch den Kakao Rahmen“ (der Haupt-Thread der Laufschleife) fehlt Ihren Fang und Absturz passieren. Sie können dies mit GCD des dispatch_synch leicht umgehen und in seinem Block-Argumente den Methodenaufruf und jede Ausnahmebehandlung setzen.

Warum verwenden NSException vorbei NSError des

Wer schon einmal Arbeit in einer der älteren C-basierten Frameworks wie Core Audio getan hat, weiß, was eine lästige Pflicht es ist die Überprüfung, Bearbeitung und Meldung von Fehlern. Der Hauptvorteil @ versuchen / @ Fang und NSExceptions bietet, ist der Code sauberer zu machen und leichter zu pflegen.

Angenommen, Sie haben 5 Zeilen Code, der die Arbeit an einer Datei. Jeder könnte man von werfen, sagen wir, drei verschiedene Fehler (zB aus Festplattenspeicher, Lesefehler, etc.). Anstatt jede Zeile in einem bedingten Einwickeln, die die Kontrollen für einen Rückgabewert NO und dann den Zeiger Untersuchung auf einen anderen ObjC Methode NSError auslagert (oder noch schlimmer, verwendet ein #define Makro!), Wickeln Sie alle 5 Zeilen in ein einzelnes @try und genau dort jeden Fehler behandeln. Denken Sie an die Zeilen, die Sie sparen!

Mit dem NSException Subklassen erstellen, können Sie auch leicht zentralisieren Fehlermeldungen und vermeiden, dass Sie Ihren Code mit ihnen übersät. Sie können auch Ihre App „nicht-tödliche“ Ausnahmen von tödlichen Programmierer Fehler (wie NSAssert) leicht unterscheiden. Sie können auch die Notwendigkeit für den „Namen“ konstant vermeiden (die Namen der Unterklasse ist der „Name“).

Beispiele für all dies und mehr Details zu den Benchmarks und Demontage sind auf diesem Blog-Eintrag ...

Ausnahmen und try / catch / finally istdas Paradigma von so ziemlich jeder anderen großen Sprache verwendet (C ++, Java, PHP, Ruby, Python). Vielleicht ist es Zeit, um die Paranoia fallen zu lassen und es auch umarmen ... zumindest in iOS.

dich allgemein fragen, ob Sie versuchen, einen Fehler zu signalisieren, oder haben Sie tatsächlich einen außergewöhnlich guten Zustand? Wenn die ehemaligen, dann ist es eine sehr schlechte Idee, unabhängig von einem Performance-Problem, real oder wahrgenommen. Wenn letzteres der Fall, es ist auf jeden Fall das Richtige zu tun.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top