8 Stimmen

Wie lassen sich geprüfte Ausnahmen bei der Portierung von Java-Code nach ObjC am besten darstellen?

Ich arbeite an der Portierung einer Java-Codebasis nach Cocoa/Objective-C für den Einsatz auf dem Desktop Mac OS X. Der Java-Code hat Lose y Lose von Methoden mit geprüften Ausnahmen wie:

double asNumber() throws FooException {
    ...
}

Wie kann man diese am besten in Objective-C darstellen? Ausnahmen oder Fehlerausgangs-Parameter?

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

o

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

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

Natürlich ist zu beachten, dass es sich hierbei um geprüft Ausnahmen in Java, muss ich entweder @try Blöcke oder if (*outError) {...} prüft, wo immer diese Methoden aufgerufen werden ( Lose von Orten).

Ich erinnere mich daran, dass ich beim Eintritt in die @try Blöcke waren früher in Objective-C teuer, in 64-Bit oder SL oder einer anderen neuen Umgebung (ich weiß es nicht mehr genau) sind sie billig. Ich bin überhaupt nicht besorgt über Abwärtskompatibilität, so bin ich definitiv die bereit sind, nur für den neuen Trend zu entwerfen.

16voto

Quinn Taylor Punkte 44113

Sie sollten Ausnahmen unbedingt vermeiden für Dinge wie das Parsen von Zahlen aus Zeichenketten. In Objective-C stehen Ausnahmen für Fehler des Programmierers, nicht für Fehler bei der Benutzereingabe oder sogar für nicht verfügbare Dateien. (Das liegt zum Teil daran, dass die Behandlung von Ausnahmen immer kostspieliger und komplexer ist als die "konventionelle" Fehlerbehandlung. Ungeachtet der Tatsache, dass Eingabe von @try Blöcke sind "Nullkosten" in 64-Bit ist es immer noch langsam, wenn tatsächlich eine Ausnahme ausgelöst wird). Natürlich dürfen Sie Ausnahmen verwenden, wie Sie wollen, aber das ist nicht der Weg von Cocoa, und Sie werden sich mit anderem Objective-C-Code in die Haare kriegen. Leute, die Ihren Code verwenden, werden unglaublich verärgert sein, dass Sie Ausnahmen in Fällen auslösen, die eigentlich nur zu einem Fehler führen sollten.

Von Apples eigene Dokumente :

"In vielen Umgebungen ist die Verwendung von Ausnahmen ziemlich alltäglich. Sie können beispielsweise eine Ausnahme auslösen, um zu signalisieren, dass eine Routine nicht normal ausgeführt werden konnte, z. B. wenn eine Datei fehlt oder Daten nicht richtig geparst werden konnten. Ausnahmen sind in Objective-C ressourcenintensiv. Sie sollten Ausnahmen nicht für die allgemeine Ablaufsteuerung oder einfach nur zur Anzeige von Fehlern verwenden. Stattdessen sollten Sie den Rückgabewert einer Methode oder Funktion verwenden, um anzuzeigen, dass ein Fehler aufgetreten ist, und Informationen über das Problem in einem Fehlerobjekt bereitstellen."

Schauen Sie sich an, wie eingebaute Cocoa-Klassen Fehler wie diesen behandeln. Zum Beispiel, NSString hat Methoden wie -floatValue die 0 zurückgeben, wenn sie fehlschlagen. Eine bessere Lösung für Ihre spezielle Situation könnte sein, wie NSScanner tut es, wie zum Beispiel in -scanFloat: - akzeptiert einen Zeiger auf das Feld, in dem das Ergebnis gespeichert werden soll, und gibt YES o NO je nachdem, ob das Parsen erfolgreich war.

Abgesehen von den Obejctive-C Konventionen und Best Practices ist NSError viel robuster und flexibler als NSException und erlaubt es dem Aufrufer, das Problem effektiv zu ignorieren, wenn er das möchte. Ich empfehle die Lektüre der Fehlerbehandlung Programmierhandbuch für Cocoa . Anmerkung: Wenn Sie eine NSError** Param, empfehle ich Ihnen dringend, auch so zu gestalten, dass der Client die NULL wenn sie keine Fehlerinformationen erhalten möchten. Jede Cocoa-Klasse, die ich kenne, tut dies für Fehler, einschließlich NSString.

Auch wenn der portierte Code am Ende völlig anders aussieht als der Java-Code, sollten Sie sich darüber im Klaren sein, dass er von Objective-C-Code verwendet wird und nicht von denselben Clients wie das Java-Pendant. Passen Sie auf jeden Fall die Idiome der Sprache an. Der portierte Code wird kein Spiegelbild des Java-Codes sein, aber er wird dadurch viel korrekter (für Objective-C) sein.

7voto

Chris Hanson Punkte 53324

In Cocoa sollten Ausnahmen eigentlich nur für "Programmierfehler" verwendet werden. Die Philosophie ist, dass die Anwendung sie abfängt, dem Benutzer die Möglichkeit gibt, zu speichern, was er gerade tut, und zu beenden. Zum einen sind nicht alle Frameworks oder Codepfade zu 100 % ausnahmesicher, so dass dies die einzige sichere Vorgehensweise sein kann. Für Fehler, die vorhergesehen und behoben werden können, sollten Sie NSError verwenden, in der Regel über einen Out-Parameter.

3voto

Dave DeLong Punkte 240835

Sie haben Recht, dass "out Fehler sind in der Regel die bessere Lösung für ObjC". Sehr selten werden Sie in Cocoa eine API finden, die eine Ausnahme auslöst (es sei denn, Sie haben die Voraussetzungen für die API nicht erfüllt, aber in diesem Fall ist das Verhalten standardmäßig undefiniert).

Wenn Sie erwarten, dass dieser Code über Sie hinausgeht und von anderen Cocoa-Entwicklern übernommen wird, würde ich empfehlen, Fehler zu vermeiden. Ich arbeite an Code, der von Leuten erstellt wurde, die mit Cocoa nicht vertraut sind und die Ausnahmen großzügig verwenden, und sie sind ein königlicher Schmerz, um zu arbeiten.

2voto

Ben Gotow Punkte 14565

Ich bin ein großer Fan des Ansatzes, den Objective-C bei Fehlern verfolgt. Sie MÜSSEN Ausnahmen behandeln, aber Sie können sich dafür entscheiden, out-Fehler zu ignorieren, wenn Sie das wollen. Das passt zu der Einstellung von Objective-C, dass "der Programmierer weiß, was er tut". Es macht Objective-C auch zu einer sehr sauber aussehenden Sprache, weil Ihr Code nicht mit Try-Catch-Blöcken überladen ist.

Das heißt, Sie sollten das vielleicht in Betracht ziehen: Gibt es Szenarien, in denen Ausnahmen ignoriert werden? Sind die Ausnahmen, die Sie auslösen, wirklich kritisch ? Schreiben Sie selbst einfache Catch-Blöcke, die Variablen bereinigen und weitermachen? Ich würde zu out errors tendieren, weil ich die Syntax mag und Objective-C Ausnahmen nur für die kritischsten Fehler reserviert.

2voto

Gabriel Punkte 934

Es sieht so aus, als ob diese geprüften Ausnahmen sauberer zu Fehlern führen. Ausnahmen können weiterhin verwendet werden, sollten aber für außergewöhnliche Umstände reserviert werden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X