2012-04-07 5 views
31

Ich habe mich gefragt, warum ist es, dass vor einem NSError, wie unten, setzen wir: &error und nicht error?Warum wird `&` (kaufmännisches Und) vor einige Methodenparameter gesetzt?

z.

NSArray *result = [managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

Hoffnung, die Sie erklären können, ist dies auch immer die Art und Weise oder nur in bestimmten Situationen ist dies notwendig? Vielen Dank.

+1

Dies ist * Standard * C Zeiger ... der * unary * '&' Operator ist der "Adresse von" Operator.Viele gute Lektüre und * Tutorials * zum Thema und ein paar Stichworte im vorherigen Satz. –

+1

mögliches Duplikat von [Zeiger in C: wann das kaufmännische Und-Zeichen und das Sternchen zu verwenden sind] (http://stackoverflow.com/questions/2094666/pointers-in-c-when-um-die-ampersandsand-and-the- zu verwenden -asterisk) –

+0

@ user166390 Oh Mann du bist schlau !! – user3932000

Antwort

55

Sie müssen die Adresse error übernehmen, da die Funktion diese ändern muss. error wird von Zeiger übergeben, so dass Sie den "Take Address" -Operator & dafür benötigen.

C und Objective-C-Pass-Parameter von Wert. Wenn Sie error ohne ein kaufmännisches Und übergeben und die Methode, die Sie aufrufen, es ändert, Ihre Funktion, die den Aufruf vorgenommen hat, keine Änderungen angezeigt, da die Methode lokale Kopie von NSError* arbeiten würde.

Sie wissen, dass Sie ein kaufmännische vor dem entsprechenden Parameter benötigen, wenn Sie bei der Unterzeichnung des Verfahrens und sehen ** dort:

- (NSArray *)executeFetchRequest:(NSFetchRequest *)request error:(NSError **)error 
              // ^one     ^^ two 
+5

Beste Erklärung aller Zeiten. Ich wollte das schon eine Weile wissen. –

7

Der Typ des error Parameters ist (NSError **), dass ein Zeiger auf ein Zeiger auf einen NSError. Die Variable error, die Sie als Argument verwenden, wird wahrscheinlich als NSError * deklariert. Um die Typen richtig zuordnen zu können, müssen Sie die Adresse des Operators verwenden, um einen Zeiger auf einen Zeiger abzurufen (&error). Der Grund dafür, dass die Methode an erster Stelle einen Zeiger auf einen Zeiger benötigt, ist, dass sie den Wert error ändern kann und dass dieser neue Wert für Sie, den Aufrufer der Methode, verfügbar sein muss.

6

Im Wesentlichen ist die Wurzel des Problems ein Hack für das Zurückgeben eines zweiten (optionalen) Objekts.

Wie können wir das tun, da wir nur eine Sache zurückgeben können? Nun, wir könnten eine Art (return_value, error) Tupel zurückgeben, aber das ist ein bisschen unhandlich. Wir können so viele Parameter haben, wie wir möchten, können wir etwas mit diesen ...

So können Methoden/Funktionen ihre Parameter nicht ändern (um genau zu sein, sie arbeiten mit einer Kopie, so dass sie alle Änderungen machen sind lokal). Das heißt (der Nebenläufigkeitsprobleme beiseite) der Wert von fetchRequest, bevor die Nachricht in Ihrer Frage den Wert von fetchRequest danach entspricht. Beachten Sie, dass sich das Objekt, auf das fetchRequest zeigt, ändern kann, aber der Wert von fetchRequest selbst nicht.

Dies bringt uns in ein bisschen zu binden. Außer, warten Sie, wir wissen, wir können glücklich den Wert eines Parameters nehmen und modifizieren, worauf es hinweist! Wenn Sie die Deklaration für executeFetchRequest:error: betrachten, werden Sie sehen, dass es eine NSError** dauert. Das ist "ein Zeiger auf einen Zeiger auf eine NSError". Also können wir ein leeres/baumelndes NSError* initialisieren, die Adresse davon (mit dem unary & operator) finden und dieses übergeben. Die Methode kann dann dem NSError* zuweisen, auf den sich dies bezieht.

Voila, wir haben effektiv optionale zusätzliche Rückgabewerte.

+0

Danke für die Erklärung. Ich glaube, ich verstehe es fast. Ich verstehe, dass eine lokale Kopie von fetchRequest in der Methode gemacht wird, um so zu arbeiten, dass die ursprüngliche fetchRequest unverändert bleibt. Aber warum ändert sich dann das Objekt, auf das fetchRequest verweist, aber der Wert von fetchRequest nicht? – marciokoko

+0

Probieren Sie diese Analogie: Ich sage Ihnen, "zählen Sie die Dateien in Box 3 drüben und sagen Sie mir, wie viele es gibt". Ich bin der Anrufer, und ich habe dir einen Zeiger gegeben. Sie können jetzt tun, was immer Sie möchten, mit dem Inhalt von Box 3 (ändern Sie das Objekt an dem angegebenen Zeiger), und Sie können sogar entscheiden, dass Sie ignorieren, was ich Ihnen gesagt habe und schauen Sie sich Box 2 an, aber keine von das beeinflusst den Wert von dem, was ich dir gegeben habe (der Kontext des Anrufers) –

+0

Verstand durchgebrannt! Einverstanden! Verstanden ... muss für spätere Verwendung parsen! – marciokoko

Verwandte Themen