2010-01-14 19 views
8

Beispiel: Die -save: Methode von NSManagedObjectContext wird wie folgt erklärt:Was ist der Punkt von (NSError **) Fehler?

- (BOOL)save:(NSError **)error 

Da NSError bereits eine Klasse ist, und tatsächlich haben die Wirkung der Änderung dieser Aufgabe -save: innerhalb der Implementierung würde einen Zeiger vorbei, was ist der Punkt hier einen Zeiger auf einen Zeiger zu übergeben? Was ist der Vorteil/Sinn?

Anwendungsbeispiel:

NSError *error; 
if (![managedObjectContext save:&error]) { 
    // Handle the error. 
} 
+3

Sie sollten Fehler zu Null in diesem Beispiel initialisieren – ergosys

+7

Nein, es gibt absolut keine Notwendigkeit, den Fehler auf Null zu initialisieren. Der Wert des Fehlers ist bei der Rückkehr aus der Methode ** völlig undefiniert, es sei denn ** die Methode gab nil oder NO zurück. – bbum

+0

Ich hatte NSErrors immer auf Null initialisiert, aber ich vermute ich lag falsch in meiner Interpretation, wie Fehler intern behandelt wurden: http://rentzsch.tumblr.com/post/260201639/nserror-is-hard –

Antwort

16

Wenn Sie nur einen Zeiger übergeben haben, würde die gesamte Methode das bereits vorhandene NSError-Objekt ändern, auf das Sie zeigen.

Durch die Übergabe eines Zeigers an einen Zeiger kann er neue NSError-Objekte erstellen und Sie mit einem Zeiger beliefern, der auf sie zeigt.

+5

Sortieren von. Wenn Sie einen Verweis auf einen vorhandenen NSError übergeben, müsste die NSError-Implementierung die Änderbarkeit unterstützen. Das wäre ein ganz anderer API-Vertrag. Ansonsten, richtig. – bbum

+0

Ich habe eine relevante Reihe von Beispielen zu dieser Frage hinzugefügt. http://stackoverflow.com/questions/16244597/nserror-returned-with-bad-address-why – bbum

3

Es ermöglicht das Verfahren eine neue NSError zuzuweisen und den Zeiger ändern, um es zu zeigen, anstatt die NSError bereits darauf modifizieren zu müssen (was, wenn es nicht groß genug ?)

+0

Ich bin verwirrt. Wenn Sie die Adresse an einen NULL-Fehler senden, gibt es keinen NSE-Fehler, den Sie ändern können, bis Sie einen erstellen. Außerdem ist NSError unveränderlich, daher können Sie es gemäß MacMark oben nicht bearbeiten. Ich wünschte, ich könnte all diese widersprüchlichen Antworten verstehen. –

3

Der Vorteil ist, dass Sie das NSError-Objekt nicht erstellen müssen. Da die Dokumentation heißt es:

Ein Zeiger auf ein Objekt NSError Sie müssen keine NSError Objekt erstellen.“

+0

Können Sie mehr Klärung dazu, mit einem Beispiel vielleicht, weil MacMark oben sagt 'NSError' ist unveränderlich, so dass Ihr nur Die Wahl besteht darin, eine zu erstellen. Ich nehme an, du meinst, der CALLER muss keinen 'NSError' erstellen, aber wenn ein Fehler zurückgegeben wird, dann muss der CALLED sicherlich einen' NSError' erstellen. Deine Antwort ist ein wenig unklar. –

6

@Anon korrekt ist. Ich füge hinzu: Dies ist die Cocoa-Möglichkeit, Fehler zu erzeugen, anstatt Ausnahmen zu werfen.

In Ihrem Beispiel haben Sie:

NSError *error = nil; 
if (![managedObjectContext save:&error]) { 
    // Handle the error. 
} 

Unmittelbar nach dem Aufruf von save:, wenn ein Fehler aufgetreten ist, dann ist die save: Methode wird ein neues NSError Objekt erstellt hat, und veränderte Ihre error Variable-zu-Punkt von nil zu dem neuen Fehlerobjekt. Auf diese Weise können Sie das Objekt NSError selbst untersuchen und angemessen darauf reagieren.

IMO, das ist sauberer als eine Ausnahme zu werfen (was in meiner Philosophie sollte nur getan werden, wenn etwas katastrophal und unwiederbringlich passiert).

12

Es ist, was einige Leute als "out" -Parameter bezeichnen.

Sie übergeben keinen Zeiger an ein NSError-Objekt. Sie übergeben einen Zeiger an eine lokale Variable. Dies gibt der aufgerufenen Methode die Möglichkeit, Ihre lokale Variable zu ändern. In diesem Fall, um es einer NSError-Instanz zuzuordnen.

Vielleicht verwirrend ist, dass die lokale Variable, die Sie an save: übergeben, selbst ein Zeiger ist, so dass der Variablentyp ein Zeiger auf einen Zeiger ist.

Die untere Zeile, es ist ein Zeiger auf eine lokale Variable, und es funktioniert das gleiche, ob die lokale Variable int oder NSError* ist.

+0

macht jetzt sehr viel Sinn. Danke an alle! tolle Sachen ... – openfrog

+0

Ich mag Ihre Erklärung, aber ich bin ungebildet darin, wie eine Null lokale Variable eine gültige Adresse hat, die Sie an eine andere Methode weitergeben können. Können Sie das Stück näher erläutern? –

1

Wenn Sie nur in einem Zeiger übergeben, alle das Verfahren Objekt des bereits bestehende NSError verändern würde tun können, die Sie verweisen auf .

Sie können ein NSError-Objekt nicht ändern.

NSError ist unveränderlich. Aus diesem Grund benötigen Sie den Zeiger auf die Variable NSError. Sie können nur einen brandneuen NSError erstellen. So ändern Sie den Zeiger, um auf Ihren neu erstellten NSError zu zeigen.

Verwandte Themen