08、值类型的Copy-On-Write
Copy-On-Write的理解
当我们这样定义一个Array的时候:
var numbers1 = [1, 2, 3, 4, 5]
虽然Swift中的Array是一个struct,但numbers1中的数字并不保存在numbers1对象里,它们会另外存储在系统堆内存中。numbers1对象里,只会保存指向堆内存的一个引用。我们可以用下面的代码确认这个事情:
MemoryLayout.size(ofValue: numbers1) // 8
可以看到,这段代码的返回的结果是8,也就是一个64位内存地址占用的空间,事实上,无论数组里存放多少元素,一个Array对象的大小都是一个内存地址的大小。
此时,如果我们复制一个numbers1对象:
var numbers2 = numbers1
由于Array实现了Copy-On-Write机制,numbers1和numbers2会指向系统堆中的同一个位置。直到我们修改了其中的一个对象:
numbers2[0] = 11
这时,numbers2就会拷贝numbers1的内容,并把数组第一个位置的值设置成11。但是,假设没有numbers2,分配出来的系统堆就只会有numbers1对象的一个引用。这时,先拷贝原数组的值,再进行修改就显得多余了,作为一项可以优化的手段,我们可以选择直接在numbers1的原始内存中修改。