Wenn Sie einen Parameter in eine Methode übergeben wird kopiert und später in Ihrer Methode geht man mit dieser Kopie:
- (void)changeA:(NSInteger)aToChange {
aToChange = 7;
}
Dann, wenn Sie diese Methode verwenden, werden Sie nicht in der Lage sein, den Wert zu ändern Sie bestanden aus dem Inneren dieser Methode:
NSInteger a = 42;
[smb changeA:a];
// a is still 42
das, weil drin -changeA:
Sie mit einer Kopie von Argumenten beschäftigen, das heißt, so dass Sie etwas tun, wie (Pseudocode):
// inside changeA:
NSInteger aToChange = a; // (value is copied)
aToChange = 7; // this does not modify a, right?
Sie auch die Adresse dieser aToChange
bekommen könnte und versuchen, etwas damit zu tun:
// inside changeA:
NSInteger aToChange = a; // (value is copied)
NSInteger *pointerToCOPY = &aToChange; // get address of aToChange
NSInteger *pointerToA = &a; // get address of a
// here pointerToCOPY != pointerToA
Also, um Ihren Code zurück:
NSError *error = nil; // outer error, passed as a parameter
...
- (id)doSomethingWithObj:(NSObject *)obj error:(NSError *)error
{
// NSError *error(local copy) = error(passed argument);
error = tmp; // here error is the pointer to the local error copy
return nil;
}
Wie es zuvor mit aToChange
war, Sie können Ihre externe NSError error *
nicht von innerhalb Ihrer Methode ändern. Deshalb werden Doppelzeiger verwendet, Sie senden Zeiger auf Ihren Zeiger, so dass Sie immer noch Zugriff auf die externe error
Referenz haben und sie einstellen können.
- (id)doSomethingWithObj:(NSObject *)obj error:(NSError **)error
{
// NSError **error(local copy) = error(passed argument);
*error = tmp; // Here *error is the pointer to the local error copy,
// When you dereference error you get NSError *, which you can set,
// that's your external error.
return nil;
}
Hinweis als es unmöglich ist, dies zu tun:
NSError *error = nil;
NSError *otherError = [NSError error with];
*error = otherError;
error
ist ein Zeiger auf eine Struktur, ist *error
eine Struktur, die mit einzelnem isa
Feld (von dem Punkt des ID-Typ defenition). Es ist unangemessen, einer Struktur einen Zeiger auf den Fehler (otherError
, d.h. die Plattformzeigergröße int) zuzuweisen.
Und dann die letzte Frage bleibt, warum nicht auch Sie:
NSError *error = nil;
NSError *otherError = [NSError error with];
*error = *otherError; // why can't I assign to structs?
Ich bin mir nicht ganz sicher, aber vielleicht Speicherverwaltung und ABI kommt im Spiel, hier könnte es nur Bündel kopieren von Bytes von einem Objekt zum anderen, da sie nur eine C-Struktur sind. Wie Sie wissen, ist Objective-C eine Obermenge von C, und es ist möglich, Strukturen dort zuzuordnen: Assign one struct to another in C. Das ist Objective-C-Besonderheit, die mit Objekten zu tun hat, denke ich. Alles ist ziemlich dynamisch, Sie können Klassen zur Laufzeit erstellen und Instanzvariablen hinzufügen (Mike Ash on that topic), daher ist zum Zeitpunkt der Kompilierung nicht bekannt, was über das Feld isa
in der Struktur hinausgeht, und eigentlich ist id
nur ein Zeiger auf diese Struktur mit einer einzigen isa
. Das ist keine gute Idee, einfach das einzelne isa
Struct kopieren und sagen, du bist fertig, Dinge werden auseinander fallen.
Schnelle Anmerkung; Sie brauchen 'if (error) * error = tmp;'. I.e. Sie müssen überprüfen, ob "error" nicht-'nil' ist, bevor Sie es zuweisen. – bbum