Frage

Ich arbeite eine Java-Codebasis Cocoa / Objective-C für den Einsatz auf Desktop-Mac OS X. Die Java-Code auf der Portierung hat viel und viel von Methoden mit überprüfter Ausnahmen mögen:

double asNumber() throws FooException {
    ...
}

Was ist der beste Weg, um diese in Objective-C zu vertreten? Ausnahmen oder Fehler out-Parameter?

- (CGFloat)asNumber { 
    ... // possibly [FooException raise:format:];
}

oder

- (CGFloat)asNumberError:(NSError **)outError {
    ...
}

Ich habe das Gefühl, dass out-Fehler im Allgemeinen die bessere Lösung für Objective-C sind, aber wie Sie ... eine Menge von Methoden, wie die oben wird ziemlich ungeschickt aussehende sehen können. Und wieder gibt es viel von diesen.

Natürlich denken Sie daran, dass da diese aktiviert Ausnahmen in Java, ich muss entweder @try Blöcke oder if (*outError) {...} Prüfungen einführen, wo diese Methoden aufgerufen werden ( Partien von Plätze).

Ich erinnere mich zu hören, dass bei der Eingabe @try Blöcke in Objective-C einmal teuer war, ist es billig in 64-Bit- oder SL oder einem anderen neuen env (nicht mehr genau). Ich bin nicht besorgt über die Abwärtskompatibilität, so dass ich bin auf jeden Fall nur bereit für die neuen Hotness zu entwerfen.

War es hilfreich?

Lösung

Sie sollten auf jeden Fall vermeiden Ausnahmen für Dinge wie Zahlen von Strings parsen. In Objective-C, stellen Ausnahmen Programmierer Fehler, keine Benutzereingabefehler oder gar nicht verfügbar Dateien. (Ein Teil des Grundes ist, dass die Ausnahmebehandlung wird immer teurer und komplexer als mehr „konventionelle“ Fehlerbehandlung. Unabhängig von der Tatsache, dass a href <= "http://developer.apple.com/ReleaseNotes/Cocoa/RN-ObjectiveC /index.html#//apple_ref/doc/uid/TP40004309-DontLinkElementID_11" rel = ‚noreferrer‘> @try Blöcke eintretenden ‚Null-Kosten‘ in 64-Bit-, ist langsam, wenn es immer noch eine Ausnahme tatsächlich ausgelöst wird. natürlich), sind Sie erlaubt Ausnahmen zu verwenden, wie Sie wollen, aber es ist nicht die Cocoa Art und Weise, und Sie befinden sich im Widerspruch zu anderen Objective-C-Code zu finden. Leute, die Ihren Code verwenden werden unglaublich verärgert, dass Sie Ausnahmen in Fällen werfen, die zu einem Fehler nur zur Folge haben sollten.

Apples eigene docs :

  

"In vielen Umgebungen ist die Verwendung von Ausnahmen ziemlich alltäglich. Zum Beispiel könnten Sie eine Ausnahme aus, um zu signalisieren, dass eine Routine nicht normal so ausführen konnte, wie wenn eine Datei fehlt oder Daten nicht korrekt analysiert werden konnten . Ausnahmen sind ressourcenintensiv in Objective-C. Sie keine Ausnahmen für die allgemeine Flusssteuerung oder einfach Fehler bedeuten verwenden sollten. Stattdessen sollten Sie den Rückgabewert einer Methode oder Funktion, um anzuzeigen, zu verwenden, dass ein Fehler aufgetreten ist, und bieten Informationen über das Problem in einem Fehlerobjekt. "

Schauen Sie, wie integrierte in Cocoa-Klassen Fehler wie diese handhaben. Zum Beispiel NSString hat Methoden wie -floatValue, die 0 zurück, wenn es schlägt fehl. Eine bessere Lösung für Ihre spezielle Situation könnte sein, wie NSScanner tut es, wie in -scanFloat: -. Nimm einen Zeiger auf das Feld, in dem das Ergebnis gespeichert werden soll, und das Rück YES oder NO basierend darauf, ob das Parsen erfolgreich war

Neben neuen Ziels-C-Konvention und Best Practices ist NSError viel robuster und flexibler als NSException, und ermöglicht es dem Anrufer, um effektiv das Problem zu ignorieren, wenn sie wollen. Ich schlage vor, das Lesen durch die Fehler Programmieranleitung Handling für Cocoa . Hinweis: Wenn Sie einen NSError** param akzeptieren, ich dich auch stark darauf hin, entwerfen die Client übergeben NULL zu ermöglichen, wenn sie wollen keine Fehlerinformationen erhalten. Jede Cocoa Klasse mir bewusst bin tut dies auf Fehler, einschließlich NSString.

Obwohl der portierten Code kann am Ende völlig verschieden von dem Java-Code sucht, erkennt, dass sie von Objective-C-Code verwendet werden, nicht die gleichen Kunden der äquivalenten Java. Auf jeden Fall passen die Idiome der Sprache. Die Port wird kein Spiegelbild des Java-Code sein, aber es wird viel mehr richtig (für Objective-C) als Ergebnis.

Andere Tipps

In Cocoa, Ausnahmen sind wirklich nur angeblich für verwendet werden „Programmierfehler“; die Philosophie ist die App fängt sie, gibt dem Benutzer die Möglichkeit zu lassen, zu retten, was sie tun, und zu beenden. Zum einen sind nicht alle Gerüste oder Codepfade können 100% Ausnahme sicher sein, so kann dies die einzige sichere Vorgehensweise sein. Für Fehler, die von den erwarteten und wiederhergestellt werden können, sollten Sie NSError, in der Regel über einen Out-Parameter verwenden.

Sie sind richtig, dass „out Fehler im Allgemeinen die bessere Lösung für ObjC sind“. Sehr selten finden Sie eine API in Cocoa finden, die eine Ausnahme auslöst (es sei denn, Sie haben nicht die Voraussetzungen für die API zufrieden, aber in diesem Fall ist das Verhalten standardmäßig nicht definiert).

Wenn Sie diesen Code erwarten über Sie zu leben und von anderen Cocoa-Entwickler angenommen werden, würde ich empfehlen Fehler mit aus. Ich arbeite an Code, der von Menschen nicht vertraut mit Cocoa gebaut wurde und die Ausnahmen großzügig verwendet, und sie sind ein königlichen Schmerz zu arbeiten um.

Ich bin ein großer Fan des Überschreitungsfehlers Ansatzes, dass Objective-C verwendet. Sie müssen Ausnahmen behandeln, aber Sie können wählen, um Fehler zu ignorieren, wenn Sie wollen. Sie paßt alles mit der Objective-C-Haltung, dass „der Programmierer weiß, was sie tun.“ Es macht auch Objective-C eine sehr sauber aussehende Sprache, weil der Code nicht mit Try-Catch-Blöcken überladen wird.

Das heißt - Sie könnten in Betracht ziehen: Gibt es Situationen, in denen Ausnahmen ignoriert werden? Sind die Ausnahmen, die Sie wirklich werfen kritisch ? Finden Sie sich einfach catch-Blöcke zu schreiben, die Variablen bereinigen und weiter? Ich würde in Richtung auf etwaige Fehler anlehnen, weil ich die Syntax und Objective-C Reserven Ausnahmen wie nur die kritischsten Fehler.

Das sieht aus wie diese überprüft Ausnahmen Karte mehr sauber zu out Fehler. Ausnahmen immer noch verwendet werden könnten, sollen aber für außergewöhnliche Umstände reserviert werden.

Ausnahmen sind wahrscheinlich der beste Ansatz, da das 64-Bit-Obj-C ABI (Laufzeit) Null-Kosten Ausnahmen verwendet, so erhalten Sie saubereren Code ohne real Kosten. Natürlich in 32-bit der alte setjmp / longjmp Ausnahmen sind noch im Einsatz und sie interagieren nicht mit C ++, so dass, wenn ein Ziel ist, dann haben Sie ein Problem.

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