Normalerweise lassen meine Methoden, die zur Laufzeit fehlerhaft werden können, auf einen NSError
Zeiger verweisen . Wenn bei dieser Methode tatsächlich etwas schief geht, kann ich die NSError
Referenz mit Fehlerdaten füllen und null von der Methode zurückgeben.
Beispiel:
- (id) endWorldHunger:(id)largeAmountsOfMonies error:(NSError**)error {
// begin feeding the world's children...
// it's all going well until....
if (ohNoImOutOfMonies) {
// sad, we can't solve world hunger, but we can let people know what went wrong!
// init dictionary to be used to populate error object
NSMutableDictionary* details = [NSMutableDictionary dictionary];
[details setValue:@"ran out of money" forKey:NSLocalizedDescriptionKey];
// populate the error object with the details
*error = [NSError errorWithDomain:@"world" code:200 userInfo:details];
// we couldn't feed the world's children...return nil..sniffle...sniffle
return nil;
}
// wohoo! We fed the world's children. The world is now in lots of debt. But who cares?
return YES;
}
Wir können dann die Methode so verwenden. Machen Sie sich nicht einmal die Mühe, das Fehlerobjekt zu untersuchen, es sei denn, die Methode gibt nil zurück:
// initialize NSError object
NSError* error = nil;
// try to feed the world
id yayOrNay = [self endWorldHunger:smallAmountsOfMonies error:&error];
if (!yayOrNay) {
// inspect error
NSLog(@"%@", [error localizedDescription]);
}
// otherwise the world has been fed. Wow, your code must rock.
Wir konnten auf die Fehler zugreifen, localizedDescription
weil wir einen Wert für festgelegt haben NSLocalizedDescriptionKey
.
Der beste Ort für weitere Informationen ist die Dokumentation von Apple . Es ist wirklich gut.
Es gibt auch ein schönes, einfaches Tutorial zu Cocoa Is My Girlfriend .
id
auf aBOOL
. Jede geringfügige ARC-kompatible Variation wäre sehr willkommen.BOOL
. RückgabeNO
im Fehlerfall und anstatt nach dem Rückgabewert zu suchen, prüfen Sie einfach nacherror
. Wenn Sienil
weitermachen, wenn Sie damit!= nil
umgehen.**error
nicht Null ist. Andernfalls gibt das Programm einen Fehler aus, der völlig unfreundlich ist und nicht deutlich macht, was passiert.Ich möchte einige weitere Vorschläge hinzufügen, die auf meiner letzten Implementierung basieren. Ich habe mir einen Code von Apple angesehen und denke, mein Code verhält sich ähnlich.
In den obigen Beiträgen wird bereits erläutert, wie NSError-Objekte erstellt und zurückgegeben werden, sodass ich mich nicht mit diesem Teil befassen werde. Ich werde nur versuchen, einen guten Weg vorzuschlagen, um Fehler (Codes, Nachrichten) in Ihre eigene App zu integrieren.
Ich empfehle, einen Header zu erstellen, der eine Übersicht über alle Fehler Ihrer Domain (z. B. App, Bibliothek usw.) enthält. Mein aktueller Header sieht folgendermaßen aus:
FSError.h
FSError.m
Wenn Sie nun die oben genannten Werte für Fehler verwenden, erstellt Apple einige grundlegende Standardfehlermeldungen für Ihre App. Ein Fehler kann wie folgt erstellt werden:
Die von Apple generierte Standardfehlermeldung (
error.localizedDescription
) für den obigen Code sieht folgendermaßen aus:Error Domain=com.felis.myapp Code=1002 "The operation couldn’t be completed. (com.felis.myapp error 1002.)"
Das Obige ist für Entwickler bereits sehr hilfreich, da in der Nachricht die Domäne angezeigt wird, in der der Fehler aufgetreten ist, und der entsprechende Fehlercode. Endbenutzer haben jedoch keine Ahnung, was Fehlercode
1002
bedeutet. Daher müssen wir jetzt für jeden Code einige nette Nachrichten implementieren.Bei den Fehlermeldungen müssen wir die Lokalisierung berücksichtigen (auch wenn wir lokalisierte Nachrichten nicht sofort implementieren). Ich habe in meinem aktuellen Projekt den folgenden Ansatz verwendet:
1) Erstellen Sie eine
strings
Datei, die die Fehler enthält. Strings-Dateien sind leicht zu lokalisieren. Die Datei könnte folgendermaßen aussehen:FSError.strings
2) Fügen Sie Makros hinzu, um Ganzzahlcodes in lokalisierte Fehlermeldungen umzuwandeln. Ich habe 2 Makros in meiner Datei Constants + Macros.h verwendet. Ich füge diese Datei der Einfachheit halber immer in den Präfix-Header (
MyApp-Prefix.pch
) ein.Konstanten + Makros.h
3) Jetzt ist es einfach, eine benutzerfreundliche Fehlermeldung basierend auf einem Fehlercode anzuzeigen. Ein Beispiel:
quelle
Constants+Macros.h
und importiere diese Datei in den Präfix-Header (die.pch
Datei), damit sie überall verfügbar ist. Wenn Sie meinen, dass Sie nur eines der beiden Makros verwenden, funktioniert dies möglicherweise. Vielleicht ist die Konvertierung vonint
nachNSString
nicht wirklich notwendig, obwohl ich dies nicht getestet habe..strings
Datei) befinden, da dort das Makro von Apple aussehen wird. Lesen Sie hier mehr über die VerwendungNSLocalizedStringFromTable
: developer.apple.com/library/mac/documentation/cocoa/conceptual/…FS_ERROR_LOCALIZED_DESCRIPTION
überprüft die lokalisierbare Zeichenfolge in einer aufgerufenen DateiFSError.strings
. Vielleicht möchten Sie Apples Lokalisierungshandbuch für.strings
Dateien lesen, wenn Ihnen dies fremd ist.Tolle Antwort Alex. Ein mögliches Problem ist die NULL-Dereferenzierung. Apples Referenz zum Erstellen und Zurückgeben von NSError-Objekten
quelle
Ziel c
Swift 3
quelle
Bitte beziehen Sie sich auf das folgende Tutorial
Ich hoffe, es wird für Sie hilfreich sein, aber bevor Sie die Dokumentation von NSError lesen müssen
Dies ist ein sehr interessanter Link, den ich kürzlich gefunden habe. ErrorHandling
quelle
Ich werde versuchen, die großartige Antwort von Alex und den Punkt von jlmendezbonini zusammenzufassen und eine Modifikation hinzuzufügen, die alles ARC-kompatibel macht (bisher ist es nicht so, dass ARC sich beschwert, da Sie zurückkehren sollten
id
, was "jedes Objekt" bedeutet, aberBOOL
kein Objekt ist Art).Anstatt jetzt nach dem Rückgabewert unseres Methodenaufrufs zu suchen, prüfen wir, ob dies
error
noch der Fall istnil
. Wenn nicht, haben wir ein Problem.quelle
Ein anderes Entwurfsmuster, das ich gesehen habe, beinhaltet die Verwendung von Blöcken, was besonders nützlich ist, wenn eine Methode asynchron ausgeführt wird.
Angenommen, wir haben die folgenden Fehlercodes definiert:
Sie würden Ihre Methode definieren, die einen Fehler wie folgt auslösen kann:
Und wenn Sie es dann aufrufen, müssen Sie sich nicht darum kümmern, das NSError-Objekt zu deklarieren (die Code-Vervollständigung erledigt dies für Sie) oder den Rückgabewert zu überprüfen. Sie können einfach zwei Blöcke angeben: einen, der aufgerufen wird, wenn eine Ausnahme vorliegt, und einen, der aufgerufen wird, wenn dies erfolgreich ist:
quelle
Nun, es kommt ein wenig außer Frage, aber falls Sie keine Option für NSError haben, können Sie immer den Low-Level-Fehler anzeigen:
quelle
die ich verwenden kann,
NSError.defaultError()
wenn ich kein gültiges Fehlerobjekt habe.quelle