Jak stosować copy i mutableCopy do NSArray i NSMutableArray?
Jaka jest różnica między copy
i mutableCopy
w przypadku stosowania na NSArray
lub NSMutableArray
?
To jest moje zrozumienie; czy jest poprawne?
// ** 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
8 answers
copy
i mutableCopy
są zdefiniowane w różnych protokołach (odpowiednioNSCopying
i NSMutableCopying
), a NSArray
są zgodne z obydwoma. mutableCopy
jest zdefiniowana dla NSArray
(nie tylko NSMutableArray
) i pozwala na tworzenie mutowalnej kopii oryginalnie niezmiennej tablicy:
// 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"];
Podsumowanie:
- możesz zależeć od wyniku
mutableCopy
, aby był zmienny, niezależnie od oryginalnego typu. W przypadku tablic wynikiem powinno byćNSMutableArray
. - ty nie możesz zależeć od wyniku
copy
być mutable!copy
ing anNSMutableArray
Może zwrócićNSMutableArray
, ponieważ jest to oryginalna Klasa, alecopy
każda Dowolna instancjaNSArray
tego nie zrobi.
Edit: przeczytaj ponownie oryginalny kod w świetle odpowiedzi Marka Bessey ' a. Podczas tworzenia kopii tablicy, oczywiście możesz nadal modyfikować oryginał, niezależnie od tego, co zrobisz z kopią. copy
vs mutableCopy
wpływa na to, czy nowa tablica jest zmienna.
Edit 2: Naprawiono moje (fałszywe) założenie że NSMutableArray -copy
zwróci NSMutableArray
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-06 19:26:28
Myślę, że musiałeś źle zinterpretować jak działa copy i mutableCopy. W pierwszym przykładzie myArray_COPY jest niezmienną kopią myArray. Po wykonaniu kopii można manipulować zawartością oryginalnego myArray i nie wpływać na zawartość myArray_COPY.
W drugim przykładzie tworzysz zmienną kopię tablicy myArray, co oznacza, że możesz zmodyfikować jedną kopię tablicy, nie wpływając na drugą.
Jeśli zmienię pierwszy przykład, aby spróbować wstawić / usunąć obiekty z myArray_COPY, to nie, tak jak można się spodziewać.
Być może myślenie o typowym przypadku użycia pomogłoby. Często zdarza się, że można napisać metodę, która pobiera parametr NSArray *
i zasadniczo przechowuje go do późniejszego użycia. Można to zrobić w ten sposób:
- (void) doStuffLaterWith: (NSArray *) objects {
myObjects=[objects retain];
}
...ale wtedy masz problem, że metoda może być wywołana z nsmutablearray jako argumentem. Kod, który utworzył tablicę, może nią manipulować, gdy metoda doStuffLaterWith: jest wywołane, a kiedy później trzeba użyć wartości. W aplikacji wielowątkowej zawartość tablicy może zostać zmieniona podczas iteracji , co może spowodować kilka interesujących błędów.
Jeśli zamiast tego zrobisz to:
- (void) doStuffLaterWith: (NSArray *) objects {
myObjects=[objects copy];
}
..wtedy Kopia wytworzy migawkę zawartości tablicy w momencie wywołania metody.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-04 21:28:02
Metoda "copy" zwraca obiekt utworzony przez implementację nscopying protocols copyWithZone:
Jeśli wyślesz NSString wiadomość kopiującą:
NSString* myString;
NSString* newString = [myString copy];
Wartością zwracaną będzie NSString (nie zmienny)
Metoda mutableCopy zwraca obiekt utworzony przez implementację protokołu nsmutablecopy ' s mutableCopyWithZone:
Wysyłając:
NSString* myString;
NSMutableString* newString = [myString mutableCopy];
Wartość zwracana będzie zmienna.
We wszystkich przypadkach obiekt musi zaimplementować protokół, oznaczając go, utworzy nowy obiekt copy i zwróci go tobie.
W przypadku NSArray istnieje dodatkowy poziom złożoności dotyczący płytkiego i głębokiego kopiowania.
Płytka Kopia NSArray skopiuje tylko odwołania do obiektów oryginalnej tablicy i umieści je w nowej tablicy.
Wynik jest taki, że:
NSArray* myArray;
NSMutableArray* anotherArray = [myArray mutableCopy];
[[anotherArray objectAtIndex:0] doSomething];
Wpłynie również na obiekt o indeksie 0 w oryginalnej tablicy.
Głęboka kopia będzie rzeczywiście kopiuje poszczególne obiekty zawarte w tablicy. Odbywa się to poprzez wysłanie każdemu obiektowi wiadomości" copyWithZone:".
NSArray* myArray;
NSMutableArray* anotherArray = [[NSMutableArray alloc] initWithArray:myArray
copyItems:YES];
Edytowano, aby usunąć moje błędne założenie o kopiowaniu obiektów mutowalnych
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-06 06:30:46
NSMutableArray* anotherArray = [[NSMutableArray alloc] initWithArray:oldArray
copyItems:YES];
Utworzy anotherArray
, która jest kopią oldArray
do 2 poziomów głębokich. Jeśli obiekt oldArray
jest tablicą. Co zwykle ma miejsce w większości zastosowań.
Cóż, jeśli potrzebujemy prawdziwej głębokiej kopii możemy użyć,
NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:
[NSKeyedArchiver archivedDataWithRootObject: oldArray]];
Zapewniłoby to, że wszystkie poziomy są faktycznie kopiowane, zachowując zmienność oryginalnego obiektu na każdym poziomie.
Robert Clarence D ' Almeida, Bangalore, Indie.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-30 16:38:51
Wywołujesz addObject i removeObjectAtIndex na oryginalnej tablicy, a nie na jej nowej kopii. Wywołanie copy vs mutableCopy powoduje zmianę tylko nowej kopii obiektu, a nie oryginalnego obiektu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-04 22:56:23
Mówiąc wprost,
- copy zwraca niezmienną (nie można modyfikować) kopię tablicy,
- mutableCopy zwraca zmienną (można modyfikować) kopię tablicy.
Kopia (w obu przypadkach) oznacza, że otrzymasz nową tablicę "wypełnioną" referencjami do oryginalnej tablicy (tzn. te same (oryginalne) obiekty są odwołane w kopiach.
Jeśli dodasz nowe obiekty do kopii mutableCopy, to są one unikalne dla kopii mutableCopy. Jeśli usuniesz obiekty z kopii mutableCopy są one usuwane z oryginalnej tablicy.
Pomyśl o kopii w obu przypadkach, jak o migawce w czasie oryginalnej tablicy w czasie tworzenia kopii.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-05 12:21:45
Załóżmy
NSArray *A = xxx; // A with three NSDictionary objects
NSMutableArray *B = [A mutableCopy];
Zawartość B jest obiektem NSDictionary, a nie NSMutableDictionary, prawda?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-12 04:28:36
-(id)copy always returns a immutable one & -(id)mutableCopy always returns a mutable object,that's it.
Musisz znać typ zwracanych rzeczy i deklarując nowy obiekt, któremu zostanie przypisany, zwracana wartość musi być niezmienna lub zmienna, w przeciwnym razie kompilator pokaże Ci błąd.
Obiekt, który został skopiowany nie może być modyfikowany za pomocą nowego, Są to teraz zupełnie dwa różne obiekty.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-19 09:13:27