Як перетворити 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];