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

结构体和类

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 // <>
复制代码

文章源文件地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值