美文网首页
[swift 进阶]读书笔记-第五章:结构体和类 C5P4_写

[swift 进阶]读书笔记-第五章:结构体和类 C5P4_写

作者: liaoworkinn | 来源:发表于2019-01-01 19:47 被阅读3次

结构体和类

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 // <>

文章源文件地址

相关文章

网友评论

      本文标题:[swift 进阶]读书笔记-第五章:结构体和类 C5P4_写

      本文链接:https://www.haomeiwen.com/subject/xaholqtx.html