如何制作一个数组的完全副本?
我很难找到有关在 Swift 中复制数组的信息。
我尝试使用 .copy()
。
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
在Swift中,数组具有完整的值语义,因此不需要任何花哨的东西。
var duplicateArray = originalArray
就是你所需要的。
如果您的数组内容是引用类型,则是的,这只会复制指向对象的指针。如果要深度复制内容,则可以使用map
并对每个实例执行副本操作。对于符合NSCopying
协议的Foundation类,可以使用copy()
方法:
let x = [NSMutableArray(), NSMutableArray(), NSMutableArray()]
let y = x
let z = x.map { $0.copy() }
x[0] === y[0] // true
x[0] === z[0] // false
请注意,这里存在陷阱,Swift的值语义正在努力保护你免受它们的影响。例如,由于NSArray
表示一个不可变数组,其copy
方法只是返回对自身的引用,因此上面的测试将产生意外的结果。,并得到了以下输出:
0x7fa82b0009e0
0x7fa82b012660
0x7fa82b012770
---0x7fa82b0009e0
0x7fa82b012660
0x7fa82b012770`。看起来好像没有被复制,你知道为什么吗? - Phil Niedertscheiderx[0] == x[1]
但 x[0] === y[0]
应该失败。 - Phil Niedertscheider对于 Nate 的回答,还有一种第三个选项:
let z = x.map { $0 } // different array with same objects
*编辑* 编辑从这里开始
上面的代码与下面的代码本质相同,实际上在下面使用等号运算符会更有效率,因为除非数组被更改,否则不会复制该数组(这是设计上的考虑)。
let z = x
阅读更多请点击:https://developer.apple.com/swift/blog/?id=10
* 编辑 * 编辑结束
向此数组中添加或删除内容不会影响原始数组。但是,更改数组所持有的任何对象的任何属性将在原始数组中看到。因为数组中的对象不是副本(假设数组包含的是对象,而不是基本数字)。
var array1:[String] = ["john","alan","kristen"]; print(array1); var array2 = array1.map { $0 }; print(array2); array2 [0] =“james”; print(array1); print(array2)
; - oyalhiNSCopying
,那么可以复制一个数组:let z = x.map { $0.copy as! ClassX }
。 - John PangNate是正确的。如果你正在使用原始数组,你只需要将duplicateArray分配给originalArray。
为了完整起见,如果你正在使用NSArray对象,你需要执行以下操作来进行一个完全的NSArray复制:
var originalArray = [1, 2, 3, 4] as NSArray
var duplicateArray = NSArray(array:originalArray, copyItems: true)
对于普通对象,可以实现一个支持复制的协议,并让对象类实现这个协议,例如:
protocol Copying {
init(original: Self)
}
extension Copying {
func copy() -> Self {
return Self.init(original: self)
}
}
然后是用于克隆的数组扩展:
extension Array where Element: Copying {
func clone() -> Array {
var copiedArray = Array<Element>()
for element in self {
copiedArray.append(element.copy())
}
return copiedArray
}
}
这就是大概的内容,要查看代码和示例,请查看gist
class ABC {
var a = 0
func myCopy() -> ABC {
return ABC(value: self.a)
}
init(value: Int) {
self.a = value
}
}
var arrayA: [ABC] = [ABC(value: 1)]
var arrayB: [ABC] = arrayA.map { $0.myCopy() }
arrayB.first?.a = 2
print(arrayA.first?.a)//Prints 1
print(arrayB.first?.a)//Prints 2
var duplicateArray = originalArray
? - Dharmesh Kheni