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];
Copywykonuje niezmienne kopie. Jest to bardzo przydatne, ponieważ Apple może dokonywać różnych optymalizacji. Na przykład wysłanie copydo niezmiennej tablicy zachowuje tylko obiekt i zwraca self.
Jeśli nie używasz śmiecia lub ARC pamiętaj, że -copyzachowuje obiekt.
copytworzą normalny NSArray, a nie NSMutableArray?
NSArray& NSMutableArray, NSString& NSMutableString. Ale nie na przykład, NSViewControllerktóry zawsze zawiera stan zmienny.
An NSMutableArrayjest podklasą, NSArraywięc nie zawsze będziesz musiał konwertować, ale jeśli chcesz się upewnić, że tablica nie może zostać zmodyfikowana, możesz utworzyć NSArrayjeden 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ą letsłowa kluczowego, a następnie stanie się NSArray. Jeśli zadeklarujesz użycie varsłowa kluczowego, stanie się NSMutableArray .
Przykładowy kod:
let newArray = oldArray as Array
Arraysi NSArray/ NSMutableArrays. 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.
NSMutableArraydo NSArrayzmiennej 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.
NSMutableArrayzmiennej. 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 NSMutableArrayzmiennej i wywołano w niej metody mutacji, wywołania te zakończyłyby się doesNotRespondToSelectorbłę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];