Swift中数组拷贝
var arr_1 = [Int]()
var arr_2 = [Int]()
debugPrint("arr_1:\(Unmanaged.passUnretained(arr_1 as AnyObject).toOpaque()),arr_2:\(Unmanaged.passUnretained(arr_2 as AnyObject).toOpaque())")
---------
"arr_1:0x00000001f5d8e968,arr_2:0x00000001f5d8e968"
会发现两个空数组对象的地址竟然是同一个,一般而言,只要是new出来的对象,都应该指向不同的内存地址,swift表现得不太符合常理。
如果针对数组进行添加元素操作:
arr_1.append(1)
debugPrint("arr_1:\(Unmanaged.passUnretained(arr_1 as AnyObject).toOpaque()),arr_2:\(Unmanaged.passUnretained(arr_2 as AnyObject).toOpaque())")
---------
"arr_1:0x000000028078aaf0,arr_2:0x00000001f5d8e968"
当对数组添加元素后,内存地址发生了变化。
尝试将数组清空,再次打印数组地址:
arr_1.removeAll()
debugPrint("arr_1:\(Unmanaged.passUnretained(arr_1 as AnyObject).toOpaque()),arr_2:\(Unmanaged.passUnretained(arr_2 as AnyObject).toOpaque())")
--------
"arr_1:0x00000001f5d8e968,arr_2:0x00000001f5d8e968"
分析下来,Swift中,空数组都是指向的同一个内存地址,当对数组添加元素后,会指向实际的新的地址;当非空数组的所有元素被清空后,内存地址又会重新指向新的内存地址。
查阅Swift官方文档,找到了针对array的copy-on-write优化说明:
https://developer.apple.com/documentation/swift/array
Swift的该特性,如何影响实际的开发工作呢 ?
class IntArrayWrapper {
let dataList: [Int]
init(_ data: [Int]) {
dataList = data
}
}
var arr_1 = [Int]()
let arr_2 = [Int]()
var arrWrapper = IntArrayWrapper.init(arr_1)
debugPrint("arr_1_size:\(arr_1.count),arrWrapper_dataList_size:\(arrWrapper.dataList.count)")
arr_1.append(1)
debugPrint("arr_1_size:\(arr_1.count),arrWrapper_dataList_size:\(arrWrapper.dataList.count)")
---------
"arr_1_size:0,arrWrapper_dataList_size:0"
"arr_1_size:1,arrWrapper_dataList_size:0"
会发现,针对arr_1的修改,不会影响到arrWrapper中的dataList.
原因是数组的copy-on-write优化功能 ,最初arr_1和arrWrapper.dataList指向是相同的内存地址,当执行arr_1.append(1)时,会执行一次数组内存拷贝,arr_1将指向新的内存地址,arrWrapper.dataList继续指向之前的内存地址,所以针对arr_1的改变,将不再会影响arrWrapper.dataList.