Frage

Was ist der Unterschied zwischen copy und mutableCopy, wenn entweder auf einem NSArray oder eine NSMutableArray verwendet?

Das ist mein Verständnis; korrigieren ist es?

// ** NSArray **
NSArray *myArray_imu = [NSArray  arrayWithObjects:@"abc", @"def", nil];

// No copy, increments retain count, result is immutable
NSArray *myArray_imuCopy = [myArray_imu copy];

// Copys object, result is mutable 
NSArray *myArray_imuMuta = [myArray_imu mutableCopy];

// Both must be released later

// ** NSMutableArray **
NSMutableArray *myArray_mut = [NSMutableArray arrayWithObjects:@"A", @"B", nil];

// Copys object, result is immutable
NSMutableArray *myArray_mutCopy = [myArray_mut copy];

// Copys object, result is mutable
NSMutableArray *myArray_mutMuta = [myArray_mut mutableCopy];

// Both must be released later
War es hilfreich?

Lösung

copy mutableCopy und sind in verschiedenen Protokollen definiert (NSCopying und NSMutableCopying, jeweils) und NSArray entspricht beides. mutableCopy für NSArray definiert (nicht nur NSMutableArray) und ermöglicht es Ihnen, eine veränderbare Kopie eines ursprünglich unveränderlichen Array zu machen:

// create an immutable array
NSArray *arr = [NSArray arrayWithObjects: @"one", @"two", @"three", nil ];

// create a mutable copy, and mutate it
NSMutableArray *mut = [arr mutableCopy];
[mut removeObject: @"one"];

Zusammenfassung:

  • Sie können auf dem Ergebnis von mutableCopy abhängen wandelbar zu sein, unabhängig von der ursprünglichen Art. Im Fall von Arrays, sollte das Ergebnis ein NSMutableArray sein.
  • Sie nicht ist abhängig von dem Ergebnis der copy sein wandelbar! eine copy NSMutableArraying können ein NSMutableArray zurückkehren, denn das ist die ursprüngliche Klasse ist, aber copying jede beliebige NSArray Instanz nicht.

Edit: wieder lesen Ihre ursprünglichen Code in Licht von Mark Bessey Antwort. Wenn Sie eine Kopie Ihrer Array zu erstellen, natürlich kann man immer noch die ursprüngliche unabhängig davon ändern, was Sie mit der Kopie zu tun. copy vs mutableCopy beeinflusst, ob die neue Array ist wandelbar.

Bearbeiten. 2: Fixed meiner (false) Annahme, dass NSMutableArray -copy eine NSMutableArray zurückkehren

Andere Tipps

Ich glaube, Sie müssen haben falsch interpretiert, wie kopieren und mutableCopy Arbeit. In Ihrem ersten Beispiel ist myArray_COPY eine unveränderliche Kopie arr. Nachdem die Kopie gemacht, können Sie den Inhalt des ursprünglichen myArray manipulieren, und nicht den Inhalt von myArray_COPY beeinflussen.

Im zweiten Beispiel erstellen Sie eine änderbare Kopie myArray, was bedeutet, dass Sie entweder Kopie des Arrays ändern können, ohne die anderen zu beeinflussen.

Wenn ich das erste Beispiel, um zu versuchen zu ändern zum Einfügen / Entfernen von Objekten aus myArray_COPY, es scheitert, so wie man es erwarten würde.


Vielleicht über einen typischen Anwendungsfall denken würde helfen. Es ist oft der Fall, dass Sie vielleicht eine Methode schreiben, die einen NSArray * Parameter übernimmt, und im Grunde speichert sie für eine spätere Verwendung. Sie könnten diese auf diese Weise tun:

- (void) doStuffLaterWith: (NSArray *) objects {
  myObjects=[objects retain];
}

... aber dann haben Sie das Problem, dass das Verfahren mit einer NSMutableArray als Argument aufgerufen werden. Der Code, der das Array erzeugt wird, kann es zwischen manipulieren, wenn die doStuffLaterWith: Methode aufgerufen wird, und wenn Sie später brauchen den Wert zu verwenden. In einer Multi-Threaded-Anwendung, die Inhalte des Arrays selbst geändert werden , während Sie über es sind Iterieren , die einige interessante Fehler verursachen können.

Wenn Sie diese stattdessen tun:

- (void) doStuffLaterWith: (NSArray *) objects {
  myObjects=[objects copy];
}

.. dann die Kopie zum Zeitpunkt eine Momentaufnahme des Inhalts des Arrays erstellt die Methode aufgerufen wird.

Die „Kopieren“ Methode gibt das Objekt erstellt von NSCopying Protokollen copyWithZone Implementierung:

Wenn Sie eine Kopie Nachricht senden NSString:

NSString* myString;

NSString* newString = [myString copy];

Der Rückgabewert wird ein NSString (nicht änderbare)

sein

Die mutableCopy Methode gibt das Objekt erstellt von NSMutableCopying Protokoll der mutableCopyWithZone Umsetzung:

Durch das Senden:

NSString* myString;

NSMutableString* newString = [myString mutableCopy];

Der Rückgabewert wandelbar sein.


In allen Fällen muss das Objekt, das Protokoll implementieren, es bedeutet das neue Kopie-Objekt erstellen und sendet es Ihnen.


Im Falle NSArray gibt es ein zusätzliches Maß an Komplexität in Bezug auf flachen und tiefen Kopieren.

Eine flache Kopie eines NSArray werden nur die Verweise auf die Objekte des ursprünglichen Arrays kopieren und in das neue Array platzieren.

Das Ergebnis, dass sein:

NSArray* myArray;

NSMutableArray* anotherArray = [myArray mutableCopy];

[[anotherArray objectAtIndex:0] doSomething];

auch das Objekt bei Index 0 im ursprünglichen Array auswirken wird.


Eine tiefe Kopie kopiert tatsächlich die einzelne Objekte in der Anordnung enthalten ist. Dies geschieht, indem jedes einzelne Objekt sendet das „copyWithZone:“. Botschaft

NSArray* myArray;

NSMutableArray* anotherArray = [[NSMutableArray alloc] initWithArray:myArray
                                                       copyItems:YES];

Edited meine falsche Annahme über veränderbares Objekt Kopieren entfernen

NSMutableArray* anotherArray = [[NSMutableArray alloc] initWithArray:oldArray
                                                           copyItems:YES];

wird anotherArray schaffen, die eine Kopie von oldArray ist auf 2 Ebenen tief. Wenn ein Objekt von oldArray ist ein Array. Welche ist in der Regel der Fall in den meisten Anwendungen.

Nun, wenn wir brauchen, ist ein True Tief Kopieren könnten wir verwenden,

NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:
    [NSKeyedArchiver archivedDataWithRootObject: oldArray]];

Dies würde sicherstellen, dass alle Ebenen tatsächlich kopiert werden auf jeder Ebene die Veränderlichkeit des ursprünglichen Objekts beibehalten werden.

Robert Clarence D'Almeida, Bangalore, Indien.

Du nennt addObject und removeObjectAtIndex auf der ursprünglichen Anordnung, anstatt die neue Kopie davon Sie gemacht haben. Aufruf Kopie vs mutableCopy bewirkt nur die Veränderlichkeit der neuen Kopie des Objekts, nicht das ursprüngliche Objekt.

Um es zu sagen, einfach,

  • Kopie gibt eine unveränderliche Kopie des Arrays (kann nicht geändert werden),
  • mutableCopy gibt eine veränderbare (kann geändert werden) Kopie des Arrays.

Kopieren (in beiden Fällen) bedeutet, dass Sie ein neues Array „bevölkert“ mit Objektreferenzen auf die ursprüngliche Anordnung erhalten (das heißt, die gleichen (original) Objekte werden in den Kopien verwiesen wird.

Wenn Sie neue Objekte in die mutableCopy hinzufügen, dann sind sie auf die mutableCopy einzigartig. Wenn Sie Objekte aus dem mutableCopy entfernen, werden sie aus dem ursprünglichen Array entfernt.

Denken Sie an der Kopie in beiden Fällen als Momentaufnahme in der Zeit des ursprünglichen Arrays zum Zeitpunkt der Kopie erstellt wurde.

Angenommen

NSArray *A = xxx; // A with three NSDictionary objects
NSMutableArray *B = [A mutableCopy]; 

B Inhalt ist NSDictionary Objekt nicht NSMutableDictionary, ist es richtig?

-(id)copy always returns a immutable one & -(id)mutableCopy always returns a mutable object,that's it.

Sie haben die Rückgabetyp dieser Kopier Sachen zu wissen, und während das neue Objekt deklarieren, die einen ist der Rückgabewert zugewiesen werden muss unveränderlicher oder wandelbar sein, sonst wird Compiler-Fehler angezeigt.

Das Objekt, das kopiert wurde, kann die neuen nicht geändert werden, verwenden, sie sind völlig zwei verschiedene Objekte jetzt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top