结构体和类
5.4写时复制
定义:结构体的引用在改变的一瞬间是唯一的,不会有复制发生,内存的改变将在原地进行。
不太好理解的话我们一起看下面这个demo
var x = [1,2,4]
var y = x
x.append(5) //1,2,4,5
y.removeLast() //1,2
这时,把x赋值给y时会发生复制。这时候两个数组的引用
指向的是内存中的同一个位置
。共享存储部分。
当改变x
时这个共享会被检查到。
内存将会被复制出来。
我们就独立的改变了两个变量。
耗性能的元素复制操作只会在必要的时候
发送。这个就叫做写时复制
。
通俗来说: 复制时用的是一个内存地址,当某一个集合改变时恰到好处的复制了一份出来。
已经用官方
,非官方
,简洁
的语句解释了三遍了朋友我相信你肯定懂的!
知识点: 复制结构体变量。里面进行的浅复制。对象本身不会被复制。只有引用会被复制。
写时复制的高效方法
1.首先要知道一个对象是否是唯一引用的,通过isKnownUniquelyReferenced(&obj)函数来获取。
//会返回一个Bool值告诉你是否唯一 对于OC的对象直接返回false
isKnownUniquelyReferenced(&object: T)
final class Box<A> {
var unbox:A
init(_ value:A) {
self.unbox = value
}
}
var a = Box(NSMutableData())
isKnownUniquelyReferenced(&a)//true
var b = a
isKnownUniquelyReferenced(&a)//false
isKnownUniquelyReferenced(&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 // <>
网友评论