Як перетворити NSMutableArray в NSArray в Windows Vista ціль-с?
NSArray *array = mutableArray;
Як перетворити NSMutableArray в NSArray в Windows Vista ціль-с?
NSArray *array = mutableArray;
Відповіді:
NSArray *array = [mutableArray copy];
Copy
робить незмінні копії. Це досить корисно, оскільки Apple може робити різні оптимізації. Наприклад, відправка copy
в незмінний масив зберігає лише об'єкт і повертається self
.
Якщо ви не використовуєте збір сміття або ARC, пам’ятайте, що -copy
об’єкт зберігає.
copy
створює звичайний NSArray, а не NSMutableArray?
NSArray
& NSMutableArray
, NSString
& NSMutableString
. Але не, наприклад, NSViewController
який завжди містить стан, що змінюється.
Це NSMutableArray
підклас, NSArray
тому вам не потрібно буде завжди конвертувати, але якщо ви хочете переконатися, що масив не може бути змінений, ви можете створити NSArray
будь-який із цих способів залежно від того, хочете ви його автоматично випустити чи ні:
/* Not autoreleased */
NSArray *array = [[NSArray alloc] initWithArray:mutableArray];
/* Autoreleased array */
NSArray *array = [NSArray arrayWithArray:mutableArray];
EDIT: Рішення, яке надає Георг Шьоллі, - це кращий спосіб зробити це і набагато чистіше, особливо зараз, коли у нас є ARC і навіть не потрібно викликати автовипуск.
Мені подобаються обидва основні рішення:
NSArray *array = [NSArray arrayWithArray:mutableArray];
Або
NSArray *array = [mutableArray copy];
Основна відмінність я бачу в них , як вони поводяться , коли mutableArray дорівнює нулю :
NSMutableArray *mutableArray = nil;
NSArray *array = [NSArray arrayWithArray:mutableArray];
// array == @[] (empty array)
NSMutableArray *mutableArray = nil;
NSArray *array = [mutableArray copy];
// array == nil
[mutableArray copy]
його можна спростити [nil copy]
. У предметі-c будь - яке повідомлення, надіслане до нуля, завжди буде нульовим. Важливо пам’ятати про відмінність "нічого" від "масиву, в якому нічого немає".
ви спробуйте цей код ---
NSMutableArray *myMutableArray = [myArray mutableCopy];
і
NSArray *myArray = [myMutableArray copy];
Нижче наведено спосіб перетворення NSMutableArray в 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;
У Swift 3.0 з'явився новий тип даних Array . Оголосити масив за допомогою let
ключового слова, тоді він стане NSArray. А якщо оголосити за допомогою var
ключового слова, то він стане NSMutableArray .
Приклад коду:
let newArray = oldArray as Array
В Objective-c:
NSArray *myArray = [myMutableArray copy];
Швидко:
var arr = myMutableArray as NSArray
NSArray *array = mutableArray;
Цей [mutableArray copy]
антипатерн є повним зразком коду. Перестаньте це робити для викидних змінних масивів, які є тимчасовими, і отримайте дислокацію в кінці поточної області.
Ні в якому разі час виконання не може оптимізувати марнотратне копіювання мутаційного масиву, який збирається вийти за межі, відключений до 0 і назавжди розподілений.
NSMutableArray
до NSArray
змінної не таємному його (що питання в OP становить близько). Виявлення такого значення (наприклад, як повернене значення або як властивість) може призвести до дуже важких проблем налагодження, якщо це значення було несподівано змінено. Це стосується як внутрішніх, так і зовнішніх мутацій, оскільки значення, що змінюється, є спільним.
NSMutableArray
змінної. Оскільки об'єкт ніколи не переставав бути мутаційним масивом, виклик методів, що мутують його, буде успішним та мутуватиме спільні дані. Якщо, з іншого боку, було скопійовано оригінальний змінний масив - змінивши його на незмінний масив - і потім призначивши NSMutableArray
змінну та застосувавши до нього мутаційні методи, ці виклики не матимуть doesNotRespondToSelector
помилок, оскільки об'єкт, який отримав виклик мутаційного методу, знаходиться в факт незмінний і не відповідає на ці методи.
Якщо ви створюєте масив за допомогою мутабельності, а потім хочете повернути незмінну версію, ви можете просто повернути змінний масив як "NSArray" шляхом успадкування.
- (NSArray *)arrayOfStrings {
NSMutableArray *mutableArray = [NSMutableArray array];
mutableArray[0] = @"foo";
mutableArray[1] = @"bar";
return mutableArray;
}
Якщо ви "довіряєте" абоненту трактувати (технічно все ще змінний) об'єкт повернення як незмінний NSArray, це дешевший варіант, ніж [mutableArray copy]
.
Щоб визначити, чи може він змінити отриманий об'єкт, одержувач повідомлення повинен спиратися на формальний тип повернутого значення. Якщо він отримує, наприклад, об'єкт масиву, введений як незмінний, він не повинен намагатися мутувати його . Неприйнятна практика програмування визначати, чи може об'єкт змінюватись на основі його належності до класу.
Вищеописана практика обговорюється більш докладно тут:
Найкраща практика: поверніть mutableArray.copy або mutableArray, якщо тип повернення - NSArray
я шукав відповідь у швидкому 3, і це запитання було показано як перший результат у пошуку, і я отримав натхненну відповідь від нього, ось ось код swift 3
let array: [String] = nsMutableArrayObject.copy() as! [String]
NSArray *array = [mutableArray copy];