我将如何精确复制数组?
我很难找到有关在Swift中复制数组的信息。
我尝试使用 .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
我将如何精确复制数组?
我很难找到有关在Swift中复制数组的信息。
我尝试使用 .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
Answers:
数组在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
方法仅返回对其自身的引用,因此上面的测试将产生意外的结果。
var x = [UIView(), UIView(), UIView()] var y = x for i in x { NSLog("%p", i) } println("---") for i in y { NSLog("%p", i) }
并得到以下输出:0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770 ---0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770
看起来好像没有被复制,您知道为什么吗?
x[0] == x[1]
但x[0] === y[0]
应该失败
内特是正确的。如果您正在使用基本数组,则只需将重复数组分配给originalArray。
为了完整起见,如果您使用的是NSArray对象,则可以执行以下操作以完整复制NSArray:
var originalArray = [1, 2, 3, 4] as NSArray
var duplicateArray = NSArray(array:originalArray, copyItems: true)
内特的答案还有第三种选择:
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);
NSCopying
,则复制一个数组:let z = x.map { $0.copy as! ClassX }
对于普通对象,可以做的是实现一个支持复制的协议,并使对象类像下面这样实现该协议:
protocol Copying {
init(original: Self)
}
extension Copying {
func copy() -> Self {
return Self.init(original: self)
}
}
然后是用于克隆的Array扩展:
extension Array where Element: Copying {
func clone() -> Array {
var copiedArray = Array<Element>()
for element in self {
copiedArray.append(element.copy())
}
return copiedArray
}
}
仅此而已,查看代码和示例检查了要点
object's
init函数中传递任何参数的不必要的麻烦
如果要复制某个类对象数组的项目。然后,您可以在不使用NSCopying协议的情况下遵循以下代码,但是您需要具有一个初始化方法,该方法应采用对象所需的所有参数。这是在操场上测试的示例代码。
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