翻译:原文链接:Understanding Swift Copy-on-Write mechanisms
在Swift中,我们有引用类型(类Classes)和值类型(结构体Structs, 元组Tuples, 枚举enums)。值类型有一个Copy机制: 如果你将一个值类型变量赋值给你一个变量,或者将它作为参数传递给一个函数(inoout 参数除外), 这个值类型的数据将会被Copy。你将会有两个相同内容的值,同时被声明了两个不同的内存空间。关于引用类型和值类型的区别,请参赛Apple官方内容。
既然我们要讨论Copy-on-Write机制,就有必要了解Swift对数据的存储机制。
好,我们开始吧!
什么是 Copy-on-Write?
在Swift中,当你有比较大的数据值,且需要将它赋值或者作为一个参数传递给一个函数的时候,复制它,在性能上耗能很大,因为你需要复制它的所有数据,并重新申请一份内存空间。
为了减少这个问题,Swift标准库实现了一个特殊的机制: 当对值类型数据,例如数组,只有当它的内容改变的时候才对它进行Copy,或者当它有超过一个的引用的时候。由于此值是唯一的引用,它并不需要Copy, 可以在改变它的时候进行Copy。因为,仅是赋值或者作为一个参数传递给函数的时候,并不需要对值类型的数据进行Copy,这样既能节省内存空间,也可以提高效率。
需要重点了解的是 …
Copy-on-Write , 并不是所有值类型默认实现的。是Swift标准库中某些特定类型实现的,比如数组Array,集合Collections,等等,因为并不是Swift标准库中所有值类型有这个特性,同样的,你自己创建的值类型并没有这个特性,除非你自己去实现它。后面将会介绍如何自己实现。
让我们先看看下面的例子
1 | import Foundation |
以上是Copy-on-Write实现的例子。当array1被创建并且赋值给array2的时候,因为Copy-on-Write机制,两个array有相同的内存地址。当array2被改变的时候,array2才被真正的赋值并且有了新的内存地址。
为自定义值类型实现Copy-on-Write机制
你可以为自定义的值类型实现Copy-on-Write机制,下面的例子可以在Swift的源代码中找到。编写高质量的Swift代码
1 | final class Ref<T> { |
上面的例子展示了如何通过引用类型为一个泛型值类型T添加Copy-on-Write机制。通过管理一个引用类型,当它的值不是为唯一的引用类型是返回一个新的实例,否则返回唯一的引用类型。
结语
Copy-on-Write是一个非常机智的方法来优化值类型的Copy,这个机制在Swift中被广泛应用,即使大多数的时候我们并没有直观的看到它,底层函数帮我们实现了它。但是知道它的实现原理对我们日常的编程也是非常有好处的。
以上是Copy-on-Write的所有内容,希望你喜欢。