Jak przekonwertować NSMutableArray na NSArray w cel C?
NSArray *array = mutableArray;
Jak przekonwertować NSMutableArray na NSArray w cel C?
NSArray *array = mutableArray;
Odpowiedzi:
NSArray *array = [mutableArray copy];
Copy
wykonuje niezmienne kopie. Jest to bardzo przydatne, ponieważ Apple może dokonywać różnych optymalizacji. Na przykład wysłanie copy
do niezmiennej tablicy zachowuje tylko obiekt i zwraca self
.
Jeśli nie używasz śmiecia lub ARC pamiętaj, że -copy
zachowuje obiekt.
copy
tworzą normalny NSArray, a nie NSMutableArray?
NSArray
& NSMutableArray
, NSString
& NSMutableString
. Ale nie na przykład, NSViewController
który zawsze zawiera stan zmienny.
An NSMutableArray
jest podklasą, NSArray
więc nie zawsze będziesz musiał konwertować, ale jeśli chcesz się upewnić, że tablica nie może zostać zmodyfikowana, możesz utworzyć NSArray
jeden z tych sposobów, w zależności od tego, czy chcesz ją automatycznie wydać, czy nie:
/* Not autoreleased */
NSArray *array = [[NSArray alloc] initWithArray:mutableArray];
/* Autoreleased array */
NSArray *array = [NSArray arrayWithArray:mutableArray];
EDYCJA: Rozwiązanie dostarczone przez Georga Schölly to lepszy sposób na zrobienie tego i dużo czystsze, szczególnie teraz, gdy mamy ARC i nawet nie musimy wywoływać automatycznego wydawania.
Lubię oba z dwóch głównych rozwiązań:
NSArray *array = [NSArray arrayWithArray:mutableArray];
Lub
NSArray *array = [mutableArray copy];
Podstawowa różnica widzę w nich jest to, jak się zachowują, gdy mutableArray jest zerowa :
NSMutableArray *mutableArray = nil;
NSArray *array = [NSArray arrayWithArray:mutableArray];
// array == @[] (empty array)
NSMutableArray *mutableArray = nil;
NSArray *array = [mutableArray copy];
// array == nil
[mutableArray copy]
można to uprościć [nil copy]
. W celu-c każda wiadomość wysłana do zera zawsze będzie zerowa. Ważne jest, aby pamiętać o rozróżnieniu między „niczym” a „tablicą bez niczego”.
próbujesz tego kodu ---
NSMutableArray *myMutableArray = [myArray mutableCopy];
i
NSArray *myArray = [myMutableArray copy];
Poniżej znajduje się sposób na konwersję NSMutableArray na NSArray:
//oldArray is having NSMutableArray data-type.
//Using Init with Array method.
NSArray *newArray1 = [[NSArray alloc]initWithArray:oldArray];
//Make copy of array
NSArray *newArray2 = [oldArray copy];
//Make mutablecopy of array
NSArray *newArray3 = [oldArray mutableCopy];
//Directly stored NSMutableArray to NSArray.
NSArray *newArray4 = oldArray;
W Swift 3.0 wprowadzono nowy typ danych Array . Zadeklaruj tablicę za pomocą let
słowa kluczowego, a następnie stanie się NSArray. Jeśli zadeklarujesz użycie var
słowa kluczowego, stanie się NSMutableArray .
Przykładowy kod:
let newArray = oldArray as Array
Array
si NSArray
/ NSMutableArray
s. One nie są takie same.
W celu c:
NSArray *myArray = [myMutableArray copy];
W krótkim:
var arr = myMutableArray as NSArray
NSArray *array = mutableArray;
Ten [mutableArray copy]
antywzorzec projektowy jest całym przykładowy kod. Przestań to robić w przypadku rzutowanych zmiennych tablic, które są przejściowe i zostają zwolnione na końcu bieżącego zakresu.
Nie ma możliwości, aby środowisko wykonawcze zoptymalizowało marnotrawstwo kopiowania zmiennej tablicy, która właśnie wychodzi poza zakres, dekrefuje do zera i zostaje na stałe zwolniona.
NSMutableArray
do NSArray
zmiennej nie ukryje jej (o to chodzi w pytaniu PO). Ujawnienie takiej wartości (na przykład jako wartości zwracanej lub jako właściwości) może spowodować bardzo trudne problemy z debugowaniem, jeśli ta wartość zostanie nieoczekiwanie zmutowana. Dotyczy to zarówno wewnętrznych, jak i zewnętrznych mutacji, ponieważ zmienna wartość jest wspólna.
NSMutableArray
zmiennej. Ponieważ obiekt nigdy nie przestał być zmienną tablicą, wywołanie na nim metod mutacji zakończy się powodzeniem i zmutuje udostępnione dane. Z drugiej strony, jeśli oryginalna zmienna tablica została skopiowana - zmieniając ją w niezmienną tablicę - a następnie przypisana do NSMutableArray
zmiennej i wywołano w niej metody mutacji, wywołania te zakończyłyby się doesNotRespondToSelector
błędami, ponieważ obiekt, który otrzymał wywołanie metody mutacji, znajduje się w fakt niezmienny i nie reaguje na te metody.
Jeśli konstruujesz tablicę poprzez mutację, a następnie chcesz zwrócić niezmienną wersję, możesz po prostu zwrócić tablicę mutable jako „NSArray” poprzez dziedziczenie.
- (NSArray *)arrayOfStrings {
NSMutableArray *mutableArray = [NSMutableArray array];
mutableArray[0] = @"foo";
mutableArray[1] = @"bar";
return mutableArray;
}
Jeśli „zaufasz” dzwoniącemu do traktowania (zwracanego technicznie wciąż zmiennego) obiektu zwrotnego jako niezmiennego NSArray, jest to tańsza opcja niż [mutableArray copy]
.
Aby ustalić, czy może zmienić odebrany obiekt, odbiorca wiadomości musi polegać na formalnym typie zwracanej wartości. Jeśli otrzyma na przykład obiekt tablicy o typie niezmiennym, nie powinien próbować go mutować . Nie jest akceptowalną praktyką programistyczną ustalanie, czy obiekt można modyfikować na podstawie jego przynależności do klasy.
Powyższą praktykę omówiono bardziej szczegółowo tutaj:
Najlepsza praktyka: Zwróć mutableArray.copy lub mutableArray, jeśli typem zwrotu jest NSArray
NSArray *array = [mutableArray copy];