由于完全值语义,现在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
答案 0 :(得分:19)
问题是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)
答案 1 :(得分:13)
数组是值类型(struct),因此它们是按值传递的,而不是通过引用传递的。
也就是说,如果你创建一个数组类型的变量并为它分配不可变数组,那么实际创建并分配不可变数组的副本 - 当然该副本与原始不可变数组没有任何关系(除此之外)在创建时具有相同的值。)
let immutable = [1, 2, 3]
//immutable[0] = 1 // Fails, ok
var mutable = immutable
mutable[0] = 5
在您的情况下,您正在访问NSArray
AnyObject
的{{1}}的不可变数组(请参阅documentation)。你可以在swift中将它用作数组,复制它并修改如下:
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
属性
答案 2 :(得分:1)
就像用数组声明var
一样简单。
var items = toolbar.items
现在您可以更改项目,然后重新分配到工具栏。
toolbar.items = items
请注意, can 不能(从Beta 3开始)改变用let
声明的“不可变”数组的元素。只是数组的长度是是固定的,这就是你不能删除项目的原因。
但是,根据Apple的UIToolbar
文档,items
数组已经是可变的。
SWIFT
var items: [AnyObject]!
答案 3 :(得分:1)
经过测试+工作:
var mutable : [UIBarButtonItem] = []
for button in toolbar.items {
mutable += button as UIBarButtonItem
}
mutable.removeAtIndex(2)
toolbar.setItems(mutable, animated: true)
答案 4 :(得分:1)
从阵列的特定索引中删除对象。
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)
答案 5 :(得分:0)
在Beta3中,常量数组是完全不可变的,而变量数组是完全可变的。所以只需将let array:更改为var array:然后验证您的代码