Как создать изменяемую копию неизменяемого массива в swift?

Теперь, когда Swift Array действительно неизменяемы благодаря полной семантике значений, как я могу создать изменяемую копию неизменяемого массива? Аналогично Obj-C mutableCopy(). Я могу, конечно, сжать массив в NSArray и использовать mutableCopy(), но не хочу использовать NSArray, потому что он не строго типизирован.

У меня есть toolbar, который имеет items из раскадровки. Я хочу удалить элемент с панели инструментов и использовать toolbar.setItems. Я хотел сделать это без кавычки как NSArray, потому что ни одна из этих функций не принимает NSArrays, они берут [AnyObject].

Очевидно, теперь, когда я вызываю removeAtIndex(), это не работает, что является правильным. Мне просто нужен mutableCopy

Простое назначение var не работает для меня и дайте 'Immutable value of type [AnyObject]'

var toolbarItems = self.toolbar.items
toolbarItems.removeAtIndex(2) //Immutable value of type [AnyObject]

Я использую Beta 3

Ответ 1

Проблема заключается в том, что self.toolbar.items является неявно развернутым необязательным (типа [AnyObject]!), и они всегда неизменяемы. Когда вы назначаете переменную toolbarItems без явного указания ее типа, она также становится неявно разворачиваемой необязательной и, следовательно, также неизменной.

Чтобы исправить это, выполните следующие действия:

var toolbarItems:[AnyObject] = self.toolbar.items
toolbarItems.removeAtIndex(2)

Или:

var toolbarItems = self.toolbar.items as [AnyObject]
toolbarItems.removeAtIndex(2)

Обновление

Как и в Xcode 6 Beta 5, вы можете обновлять коллекции, которые хранятся в необязательных переменных, поэтому исходный код теперь работает:

var toolbarItems = self.toolbar.items
toolbarItems.removeAtIndex(2)

Ответ 2

Массивы - это типы значений (struct), поэтому они передаются по значению, а не по ссылке.

Тем не менее, если вы создаете переменную типа массива и присваиваете ей неизменяемый массив, то копия неизменяемого массива фактически создается и назначается ему - и, конечно, эта копия не имеет отношения к исходному неизменяемому массиву (кроме того, имея те же значения во время создания).

let immutable = [1, 2, 3]

//immutable[0] = 1 // Fails, ok

var mutable = immutable

mutable[0] = 5

В вашем случае вы получаете доступ к неизменяемому массиву, который является NSArray of AnyObject (см. documentation). Вы можете использовать его как Массив в быстрой, сделать его копию и изменить следующим образом:

let immutable : NSArray = [ 1, 2, 3 ]

//immutable[0] = 1 // Fails, ok

var mutable : [AnyObject] = immutable

mutable.removeAtIndex(1) // mutable now is [1, 3]

mutable[0] = 7 // mutable now is [7, 3]

После того, как вы закончите с изменениями, вы можете назначить свойству items

Ответ 3

Это так же просто, как объявление var с вашим массивом.

var items = toolbar.items

Теперь вы можете изменять элементы, а затем переназначать на панель инструментов.

toolbar.items = items

Обратите внимание, что вы can не можете (начиная с Beta 3) изменять элементы "неизменяемого" массива, объявленного с помощью let. Исправлена ​​длина массива , поэтому вы не можете удалить элементы.

Однако, согласно документации Apple UIToolbar, массив items уже изменен.

СВИФТ
var items: [AnyObject]!

Ответ 4

Протестировано + работает:

    var mutable : [UIBarButtonItem] = []
    for button in toolbar.items {
        mutable += button as UIBarButtonItem
    }
    mutable.removeAtIndex(2)
    toolbar.setItems(mutable, animated: true)

Ответ 5

ИЗМЕНИТЬ ОБЪЕКТ ИЗ ОПРЕДЕЛЕННОГО ИНДЕКСА МАССЫ.

let fullArray : NSArray = Userdefaults().value(forKey: "YOUR_ARRAY_STRING") as! NSArray
var mutableArray : [AnyObject] = fullArray as [AnyObject]
mutableArray.remove(at: INDEX_TO_REMOVE) //Eg: mutableArray.remove(at: 0)
mutableArray.append(ARRAY_TO_APPEND)

Ответ 6

В Beta3 постоянные массивы полностью неизменяемы, а переменные массивы полностью изменяемы. Так что просто измените let array: на var array: а затем проверьте свой код