Frage

Ich habe gerade einen iPhone App Programmierkurs abgeschlossen. Im Rahmen des Kurses, ich sah

  • Objective-C bietet die Ausnahmebehandlung mit der @try Richtlinie
  • Die Systembibliothek nicht verwendet Ausnahmebehandlung nicht, lieber return nil

Ich fragte, ob ich die Ausnahmebehandlung für neuen Code verwenden soll ich schrieb (zB wenn ich sowohl den Front-End und Logik-Code schreiben, so dass die Kommunikation zwischen ihnen in meinen Händen), aber ich wurde nicht gesagt, sollte man nicht verwenden Ausnahmen für neuen Code. (Aber er scheiterte zu erarbeiten, dann die Klasse bewegt, ich dachte, vielleicht der Grund, später klar werden würde ..)

Sicher Ausnahmen sind überlegen return nil? Sie können bestimmte Arten fangen, werden Sie sie nicht versucht zu ignorieren, indem Sie den Rückgabetyp einer Funktion zu ignorieren, die normalerweise erfolgreich ist, müssen Sie Textnachrichten, die protokolliert werden können, erlauben sie den Code auf der Normalfall zu konzentrieren und damit besser lesbar sein. Warum Ausnahmen verwenden .

Also, was denken Sie? War mein Trainer Recht Objective-C Ausnahmen nicht zu benutzen? Wenn ja, warum?

War es hilfreich?

Lösung

Es ist nicht sicher Ausnahmen unter Umständen zu werfen, wo die Ressourcen nicht automatisch verwaltet. Dies ist der Fall des Cocoa Framework (und Nachbar-Frameworks), da sie manuelle Referenzzählung verwendet werden.

Wenn Sie eine Ausnahme werfen, jeder release Anruf Sie durch Abwickeln des Stapels überspringen wird in einem Leck führen. Dies sollte begrenzen Sie tothrowing nur, wenn Sie sicher, dass Sie gehen zu erholen nicht, da alle Ressourcen auf das OS, wenn ein Prozess quitt zurückgegeben werden.

Leider NSRunLoops neigen alle Ausnahmen zu fangen, die sie verbreiten, so dass, wenn Sie während einer Veranstaltung werfen, werden Sie auf die nächste Veranstaltung wieder aufnehmen. Dies ist offensichtlich sehr schlecht. Daher ist es besser, dass man einfach nicht werfen.

Dieses Problem verringert wird, wenn Sie verwenden Garbage Collection Objective-C, da jede Ressource, die von einem Objective-C-Objekt dargestellt wird ordnungsgemäß freigegeben werden. Jedoch C Ressourcen (wie Datei-Deskriptoren oder malloc zugewiesene Speicher), die nicht in einem Objective-C Objekt gewickelt werden immer noch undicht werden.

Also, alles in allem, nicht werfen.

Die Cocoa-API verfügt über mehrere Abhilfen für diese, wie Sie bereits erwähnt. Wiederkehr nil und das NSError** Muster sind zwei von ihnen.

Klärungen für ARC

ARC Benutzer wählen können, aktivieren oder zu deaktivieren vollständiger Ausnahme Sicherheit. Wenn Exception-Sicherheit aktiviert ist, wird ARC-Code erzeugen starke Bezüge zu lösen, wenn deren Umfang getötet wird, so dass es sicher Ausnahme verwenden in Ihrem Code . ARC werden keine externen Bibliotheken Patch in ihnen Ausnahme-Unterstützung zu aktivieren, so dass Sie sollten vorsichtig sein, wo Sie (und vor allem, wo Sie fangen) werfen, auch mit Unterstützung Ausnahme aktiviert in Ihrem Programm.

ARC Ausnahme Unterstützung kann mit -fobjc-arc-exceptions oder deaktiviert mit -fno-objc-arc-exceptions aktiviert werden. Standardmäßig wird es in Objective-C deaktiviert, sondern ermöglicht in Objective-C ++.

Volle Sicherheits Ausnahme in Objective-C ist standardmäßig deaktiviert, da die Autoren Clang davon aus, dass Objective-C-Programme werden nicht von einer Ausnahme erholen sowieso, und da gibt es eine große Codegröße Kosten und eine geringe Leistungseinbuße verbunden zu dieser Bereinigung . In Objective-C ++, auf der anderen Seite, C ++ stellt bereits eine Menge von Bereinigungscode, und die Leute sind viel eher um tatsächlich benötigte Ausnahme-Sicherheit.

Das ist alles aus dem ARC-Spezifikation auf der LLVM Website .

Andere Tipps

In Cocoa und iOS-Programmierung, sind Ausnahmen verwendet nicht behebbaren Programmierer Fehler anzuzeigen. Wenn eine Ausnahme von den Rahmenbedingungen ausgelöst wird, zeigt es an, dass die Rahmenbedingungen in einen Fehlerzustand festgestellt haben, dass beide nicht erstattungsfähig und für die ist der innere Zustand ist jetzt nicht definiert.

Wie gut, Ausnahmen durch Framework-Code geworfen die Rahmenbedingungen in einem undefinierten Zustand verlassen. D. h Sie können nicht so etwas wie tun:

void a() {
    @throw [MyException exceptionWithName: @"OhNoes!"  ....];
}

@try {
    ... call into framework code that calls a() above ...
} @catch (MyException e) {
    ... handle e ...
}

Fazit:

Ausnahmen sind nicht für die Ablaufsteuerung, Benutzereingabevalidierung, Datengültigkeitserkennung oder auf andere Weise zeigen behebbare Fehler in Cocoa verwendet werden. Dazu verwenden Sie das NSError** Muster wie dokumentiert hier (dank Abizem).

(Beachten Sie, dass es eine kleine Anzahl von API ist, dass dies nicht verletzt -.., Wo eine Ausnahme verwendet wird, einen wiederherstellbaren Zustand, um anzuzeigen, Bugs hat gegen diese eingereicht worden deprecate und schließlich diese Inkonsistenzen entfernen)


Schließlich gefunden Dokument ich war auf der Suche nach:

Wichtig: Sie sollten die Nutzung reservieren von Ausnahmen für die Programmierung oder unerwartete Laufzeitfehler wie Out-of-begrenze Sammlung Zugang, Versuche, unveränderliche Objekte zu mutieren, eine ungültige Nachricht senden, und zu verlieren die Verbindung zum Window-Server. Sie nehmen in der Regel kümmern sich um diese Art von Fehlern mit Ausnahmen, wenn ein Anwendung wird erstellt eher als zur Laufzeit.

Wenn Sie einen vorhandenen Körper des Codes haben (Wie beispielsweise Fremd Library), dass verwendet Ausnahmen Griff Fehler Bedingungen, können Sie den Code verwenden, wie sie ist in Ihrer Cocoa-Anwendung. Aber du sollte sicherstellen, dass jeder erwartet Laufzeit Ausnahmen nicht entkommen diese Subsysteme und am Ende in der Anrufer Code. Zum Beispiel kann ein Parsing Bibliothek verwenden könnte Ausnahmen intern Probleme, um anzuzeigen, und einen schnellen Ausstieg aus einer Analyse ermöglichen Zustand, die tief rekursiv sein könnte; Sie sollten jedoch darauf zu fangen nehmen solche Ausnahmen auf der obersten Ebene die Bibliothek und übersetzen sie in eine entsprechender Rückgabecode oder Staat.

Ich denke, und andere werden mich korrigieren, wenn ich falsch bin, sollten die Ausnahmen zu fangen Programmierer Fehler verwendet werden, während die NSError Art der Fehlerbehandlung für Ausnahmebedingungen verwendet werden, die auftreten, während das Programm ausgeführt wird.

Und wie für die Rückkehr nil, das ist nicht alles - Funktionen, die Probleme haben könnte nicht zurück nur nil, können sie auch (und soll) liefern weitere Informationen, um das NSError Objekt verwendet, das als Parameter übergeben wird.

Siehe auch

Ich persönlich sehe keinen Grund, keine Ausnahmen verwenden in Ihrem eigenen Code . Die Ausnahmemuster sind Reiniger für die Fehlerbehandlung als

  • immer einen Rückgabewert hat,
  • um sicherzustellen, dass eine der möglichen Rückgabewerte wirklich bedeutet „Fehler“
  • einen zusätzlichen Parameter übergeben, das ist ein Verweis auf ein NSError*
  • Streuen Sie den Code mit aufzuräumen Code für jeden Fehler Rückgabe oder mit expliziten gotos auf einen gemeinsamen Fehlerbereinigungs Abschnitt zu wechseln.

Sie müssen jedoch zu bedenken, dass andere Leute Code nicht zu Griff Ausnahme richtig gewährleistet ist (wenn es reine C, in der Tat ist es kann nicht Griff Ausnahmen richtig). So müssen Sie nie eine Ausnahme erlauben über die Grenzen des Codes zu verbreiten. Zum Beispiel, wenn Sie eine Ausnahme tief in den Eingeweiden eines Delegatmethode werfen, Sie müssen diese Ausnahme behandeln bevor sie an den Absender der Nachricht delegieren Rückkehr .

Die Art des Fehlers verwendet Kosten hängen von was Sie versuchen zu erreichen. Fast alle Methoden von Apple ein NSError Objekt füllen, die auf Fehler zugegriffen werden können.

Diese Art der Fehlerbehandlung kann mit einem Try-Catch-Block innerhalb eines Abschnitts des Codes in Verbindung verwendet werden:

-(NSDictionary *)getDictionaryWithID:(NSInteger)dictionaryID error:(NSError **)error
{
    @try
    {
         //attempt to retrieve the dictionary
    }
    @catch (NSException *e)
    {
        //something went wrong
        //populate the NSError object so it can be accessed
    }
}

Auf den Punkt gebracht, bestimmt der Zweck des Verfahrens die Art der Fehlerbehandlung Sie verwenden sollten. Aber oben in diesem Beispiel können Sie beides.

Eine häufige Verwendung für den Try-Catch-Block:

@try
{
    [dictionary setObject:aNullObject forKey:@"Key"];
}
@catch (NSException *e)
{
    //one of the objects/keys was NULL
    //this could indicate that there was a problem with the data source
}

Hope, das hilft.

Ich denke, Ihr Trainer richtig ist. Sie können alle Arten von Argumenten machen und gegen Ausnahmen, aber das Endergebnis ist, wenn Sie Ihren Code zu „riechen“ möchten sich an einen erfahrenen Cocoa-Entwickler, werden Sie Ihre Anwendung mit den gleichen Design-Muster, dass Apple den Einsatz in ihren Code implementieren und in deren Rahmen. Das bedeutet nils und NSErrors statt Ausnahmen.

Die Vorteile von nicht Ausnahmen verwenden, sind daher in erster Linie um die Konsistenz und Vertrautheit.

Eine andere Sache zu prüfen ist, dass ein nil in Objective C ist in der Regel ziemlich „sicher.“ Das heißt, können Sie jede Nachricht an einen nil senden und Ihre Anwendung wird nicht abstürzen.

(Ich soll auch darauf hin, dass Apple tun Verwendung Ausnahmen in einigen Orten, in der Regel, wo Sie eine API falsch verwenden.)

Wenn Sie Ausnahmen bevorzugen, dann können Sie sie verwenden. wenn Sie das tun, empfehle ich Ihnen, sie sparsam verwenden, da es sehr schwer wird (zusätzliche Ausstiegspunkte, die Sie in der Regel zu Übung zur Laufzeit haben, werde das Programm der Richtigkeit zu beweisen) zu halten.

gibt es keine Spezifikation für die Ausnahme Erwartungen für die Kunden der Handhabung; sie müssen ihr Programm halten auf der Grundlage der Dokumente (langweilig, fehleranfällig, wird wahrscheinlich nicht aufrechterhalten werden, bis eine Ausnahme ausgelöst wird).

, wenn ich sie benutzen waren, ich sie nur in sehr seltenen Fällen und Verwendung Fehlercodes oder Rückgabe Null, wenn möglich verwenden würde. plus, würde ich sie zu einer Bibliothek der internen Gebrauch und nicht die Clients Ausnahmen in der Schnittstelle (oder die Nebenwirkungen) aussetzen. Ich benutze sie nicht in objc oder C ++ (gut, ich werde sie fangen, aber ich werde werfen sie nicht).

, wie Sie in der Regel erwarten würden, sollten Sie vermeiden, dass sie mit dem Programmfluss steuern (ein gemeinsamer Missbrauch).

Es ist besser, sie zu benutzen, wenn Sie einen bestimmten Absturz zu entkommen. wenn du gehst nach vorne und schreiben den Code jetzt, empfehle ich Ihnen, nur die Schnittstelle schreiben, um die Fehler im Rahmen der Programmablauf und vermeiden Schreiben Ausnahmen zu behandeln, soweit möglich.

Korrektur Original-Beitrag: Kakao Libs bevorzugt null zurück, in einigen Fällen werden sie Ausnahmen für Sie werfen (zu fangen)

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