• Swift数组copy-on-write特性实例


    Swift中数组拷贝

    var arr_1 = [Int]()
    var arr_2 = [Int]()
    debugPrint("arr_1:\(Unmanaged.passUnretained(arr_1 as AnyObject).toOpaque()),arr_2:\(Unmanaged.passUnretained(arr_2 as AnyObject).toOpaque())")
    
    ---------
    "arr_1:0x00000001f5d8e968,arr_2:0x00000001f5d8e968"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    会发现两个空数组对象的地址竟然是同一个,一般而言,只要是new出来的对象,都应该指向不同的内存地址,swift表现得不太符合常理。
    如果针对数组进行添加元素操作:

    arr_1.append(1)
    debugPrint("arr_1:\(Unmanaged.passUnretained(arr_1 as AnyObject).toOpaque()),arr_2:\(Unmanaged.passUnretained(arr_2 as AnyObject).toOpaque())")
    
    ---------
    "arr_1:0x000000028078aaf0,arr_2:0x00000001f5d8e968"
    
    • 1
    • 2
    • 3
    • 4
    • 5

    当对数组添加元素后,内存地址发生了变化。
    尝试将数组清空,再次打印数组地址:

    arr_1.removeAll()
    debugPrint("arr_1:\(Unmanaged.passUnretained(arr_1 as AnyObject).toOpaque()),arr_2:\(Unmanaged.passUnretained(arr_2 as AnyObject).toOpaque())")
    
    --------
    "arr_1:0x00000001f5d8e968,arr_2:0x00000001f5d8e968"
    
    • 1
    • 2
    • 3
    • 4
    • 5

    分析下来,Swift中,空数组都是指向的同一个内存地址,当对数组添加元素后,会指向实际的新的地址;当非空数组的所有元素被清空后,内存地址又会重新指向新的内存地址。
    查阅Swift官方文档,找到了针对array的copy-on-write优化说明:
    https://developer.apple.com/documentation/swift/array
    Swift的该特性,如何影响实际的开发工作呢 ?

    class IntArrayWrapper {
        let dataList: [Int]
        init(_ data: [Int]) {
            dataList = data
        }
    }
    var arr_1 = [Int]()
    let arr_2 = [Int]()
    var arrWrapper = IntArrayWrapper.init(arr_1)
    debugPrint("arr_1_size:\(arr_1.count),arrWrapper_dataList_size:\(arrWrapper.dataList.count)")
    arr_1.append(1)
    debugPrint("arr_1_size:\(arr_1.count),arrWrapper_dataList_size:\(arrWrapper.dataList.count)")
    
    ---------
    "arr_1_size:0,arrWrapper_dataList_size:0"
    "arr_1_size:1,arrWrapper_dataList_size:0"
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    会发现,针对arr_1的修改,不会影响到arrWrapper中的dataList.
    原因是数组的copy-on-write优化功能 ,最初arr_1和arrWrapper.dataList指向是相同的内存地址,当执行arr_1.append(1)时,会执行一次数组内存拷贝,arr_1将指向新的内存地址,arrWrapper.dataList继续指向之前的内存地址,所以针对arr_1的改变,将不再会影响arrWrapper.dataList.

  • 相关阅读:
    elementUI 年份范围选择器实现
    Leetcode刷题详解——找到字符串中所有字母异位词
    深度学习在视频直播美颜sdk中的应用
    Jvm——垃圾回收
    使用brainconn工具绘制的大脑连接数据,比BrainNet更方便和灵活
    Android Studio Download Gradle 时慢问题解决
    【salesforce平台基础】-想到啥写点啥
    用 flink 插件chunjun实现全量+增量同步-达梦数据库到postgresql
    .NET性能优化-使用ValueStringBuilder拼接字符串
    Golang 实现word和Excel处理
  • 原文地址:https://blog.csdn.net/HelloMagina/article/details/126260931