ios 如何快速创建不可变数组的可变副本?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24721555/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:22:15  来源:igfitidea点击:

How does one create a mutable copy of an immutable array in swift?

iosarraysswift

提问by Johnston

Now that Swift's Array's are truly immutable thanks to full value semantics, how can I create an mutable copy of an immutable array? Similar to Obj-C mutableCopy(). I can of course downcast the array to an NSArray and use mutableCopy()but don't want to use NSArray because it does not strictly typed.

由于全值语义,Swift 的 Array 确实是不可变的,我如何创建不可变数组的可变副本?类似于 Obj-C mutableCopy()。我当然可以将数组向下转换为 NSArray 并使用,mutableCopy()但不想使用 NSArray,因为它没有严格键入。

I have a toolbarwhich has itemsfrom the storyboard. I want to remove an item from the toolbar and use toolbar.setItems. I wanted to do it without casting as a NSArray, because none of these functions take NSArrays, they take [AnyObject].

我有一个toolbar具有items从故事板。我想从工具栏中删除一个项目并使用toolbar.setItems. 我想在不强制转换为 a 的情况下做到这一点NSArray,因为这些函数都没有NSArrays,它们采用[AnyObject].

Obviously now when I call removeAtIndex()it does not work, which is correct. I just need a mutableCopy

显然现在当我调用removeAtIndex()它时它不起作用,这是正确的。我只需要一个 mutableCopy

Simply assigning to var does not work for me and give 'Immutable value of type [AnyObject]'

简单地分配给 var 对我不起作用并给 ' Immutable value of type [AnyObject]'

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

I am using Beta 3

我正在使用 Beta 3

回答by vacawama

The problem is that self.toolbar.itemsis an implicitly unwrapped optional (of type [AnyObject]!) and they are always immutable. When you assign to the variable toolbarItemswithout explicitly stating its type, it too becomes an implicitly unwrapped optional, and thus is immutable as well.

问题是这self.toolbar.items是一个隐式展开的可选(类型 [AnyObject]!),它们总是不可变的。当您在toolbarItems没有明确说明其类型的情况下分配给变量时,它也变成了一个隐式解包的可选项,因此也是不可变的。

To fix this do either:

要解决此问题,请执行以下任一操作:

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

Or:

或者:

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

Update

更新

As of Xcode 6 Beta 5, you can update collections that are stored in optional variables, so the original code now works:

从 Xcode 6 Beta 5 开始,您可以更新存储在可选变量中的集合,因此原始代码现在可以工作:

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

回答by Antonio

Arrays are value types (struct), so they are passed around by value and not by reference.

数组是值类型 (struct),因此它们是按值而不是按引用传递的。

That said, if you create a variable of array type and assign it the immutable array, a copy of the immutable array is actually created and assigned to it - and of course that copy has no relationship with the original immutable array (besides having the same values at the time it is created).

也就是说,如果您创建一个数组类型的变量并将其分配给不可变数组,则实际上会创建不可变数组的副本并将其分配给它 - 当然该副本与原始不可变数组没有关系(除了具有相同的创建时的值)。

let immutable = [1, 2, 3]

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

var mutable = immutable

mutable[0] = 5

In your case, you are accessing an immutable array which is an NSArrayof AnyObjects (see documentation). You can use it as an Array in swift, make a copy of it and modify as follows:

在您的情况下,您正在访问一个不可变数组,它是一个NSArrayof AnyObjects(请参阅文档)。您可以在 swift 中将其用作 Array,复制它并进行如下修改:

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]

After you're done with your changes, you can assign to the itemsproperty

完成更改后,您可以分配给items属性

回答by Mundi

It is as simple as declaring a varwith your array.

它就像var在数组中声明 a 一样简单。

var items = toolbar.items

Now you can change items and then reassign to the toolbar.

现在您可以更改项目,然后重新分配给工具栏。

toolbar.items = items

Note that you cancannot (as of Beta 3) alter the elements of an "immutable" array declared with letas well. Just the length of the array iswas fixed, which is why you cannot remove items.

请注意,您不能(从 Beta 3 开始)更改用 声明的“不可变”数组的元素let。就在数组的长度是固定的,这就是为什么你不能删除的项目。

However, according to Apple's documentation of UIToolbar, the itemsarray is already mutable.

但是,根据 Apple 的文档UIToolbar,该items数组已经是可变的。

SWIFT
var items: [AnyObject]!

迅速
var items: [AnyObject]!

回答by Ram Madhavan

TO REMOVE AN OBJECT FROM PARTICULAR INDEX OF AN ARRAY.

从数组的特定索引中删除对象。

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)

回答by Mundi

Tested + works:

测试+工作:

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

回答by Hussain Shabbir

In Beta3 constant arrays are completely immutable while variable arrays are entirely mutable. So just change let array:to var array: and then verify your code

在 Beta3 中,常量数组是完全不可变的,而变量数组是完全可变的。所以只需将 let array: 更改为 var array: 然后验证您的代码