结构体和类
5.4写时复制
定义:结构体的引用在改变的一瞬间是唯一的,不会有复制发生,内存的改变将在原地进行。
不太好理解的话我们一起看下面这个demo
var x = [1,2,4]var y = xx.append(5) //1,2,4,5y.removeLast() //1,2
复制代码
这时,把x赋值给y时会发生复制。这时候两个数组的引用
指向的是内存中的同一个位置
。共享存储部分。 当改变x
时这个共享会被检查到。 内存将会被复制出来。 我们就独立的改变了两个变量。 耗性能的元素复制操作只会在必要的时候
发送。这个就叫做写时复制
。
####通俗来说: 复制时用的是一个内存地址,当某一个集合改变时恰到好处的复制了一份出来。
已经用官方
,非官方
,简洁
的语句解释了三遍了朋友我相信你肯定懂的!
知识点: 复制结构体变量。里面进行的浅复制。对象本身不会被复制。只有引用会被复制。
写时复制的高效方法
1.首先要知道一个对象是否是唯一引用的,通过isKnownUniquelyReferenced(&obj)函数来获取。
//会返回一个Bool值告诉你是否唯一 对于OC的对象直接返回false
isKnownUniquelyReferenced(&object: T)final class Box<A> {var unbox:Ainit(_ value:A) {self.unbox = value}}var a = Box(NSMutableData())isKnownUniquelyReferenced(&a)//truevar b = a isKnownUniquelyReferenced(&a)//falseisKnownUniquelyReferenced(&b)//false
复制代码
2.然后判断为false时执行写是复制(这里详读了一遍感觉比较艰深晦涩,大家可在参考下面的Demo理解)。
struct MyData {fileprivate var _data: Box<NSMutableData>var _dataForWriting: NSMutableData {mutating get {if !isKnownUniquelyReferenced(&_data) {//检查对_data的引用是否是唯一性_data = Box(_data.unbox.mutableCopy() as! NSMutableData)print("Making a copy")}return _data.unbox}}init(_ data: NSData) {self._data = Box(data.mutableCopy() as! NSMutableData)}
}extension MyData {mutating func append(_ other: MyData) {_dataForWriting.append(other._data.unbox as Data)}
}let someBytes = MyData(NSData(base64Encoded: "wAEP/w==", options: [])!)
var empty = MyData(NSData())
var emptyCopy = empty
for _ in 0..<5 {empty.append(someBytes)}
empty // <c0010fff c0010fff c0010fff c0010fff c0010fff>
emptyCopy // <>
复制代码
文章源文件地址