Swift的Copy on Write 简称CoW

了解Copy on Write在Swift开发时非常重要,因为这是Swift Standard Library的一个基础特性。

值类型:structenum,和tuple,比如在调用函数时传递参数,就会发送副本拷贝

引用类型:class,参数传递时是引用方式

代码举例:

struct S { var data: Int = -1 }
var a = S()
var b = a				    // a 是从 b 拷贝而来,因此a和b各自独立内存存储该结构体
a.data = 42				    // 改变了 a 的值, b 不会有变动
println("\(a.data), \(b.data)")	// 打印 "42, -1"

class C { var data: Int = -1 }
var x = C()
var y = x						// x 是从 y 浅拷贝了
x.data = 42						// 修改x的值,y实例的值也会变更,因为他们共享同一份内存的值,只是分成了两个不同的指针指向
println("\(x.data), \(y.data)")	// 因此打印的值是相同的 "42, 42"

Swift 中的 Copy-on-Write (简称 CoW) 是一种优化策略,用于减少不必要的数据复制,从而提高性能和内存使用效率。它主要应用于 Swift 的值类型,如字符串(String)、数组(Array)、字典(Dictionary)等。

示例:

基本概念:

  • 当你将一个值类型的变量赋值给另一个变量时,Swift 默认进行浅拷贝。也就是说,两个变量实际上引用相同的内存地址。
  • 只有在其中一个变量修改其内容时,Swift 才会进行实际的拷贝操作,也就是深拷贝。这确保了只有必要时才消耗资源进行拷贝。

注意事项:

  • 1.不要提前优化:

    Swift 的标准库已经为你实现了 CoW,因此大多数情况下你不需要手动优化。

    只有在遇到性能瓶颈,且确定是由不必要的拷贝引起的时,才考虑实现自定义的 CoW。

  • 2.正确管理引用类型:

    如果你的值类型(如结构体或枚举)包含引用类型(如类实例),确保正确管理内存。

    在修改引用类型属性时要特别小心,以免意外地改变所有共享该数据的实例。

  • 3.避免无意的拷贝:

    在处理大型数据结构时,避免无意中触发 CoW。例如,尽量不要在循环中修改数组元素的属性,因为这可能会导致重复的拷贝。

  • 4.自定义类型的 CoW 实现:

    如果你需要为自定义的值类型实现 CoW,确保只在必要时进行拷贝。

    可以使用引用计数来跟踪变量的拷贝数量,当计数大于 1 时执行拷贝。

  • 5.性能测试和分析:

    使用性能分析工具(如 Xcode 中的 Instruments)来监控你的应用是否有效地使用了 CoW。

    确保任何自定义的 CoW 实现不会引入新的性能问题。

CoW 是 Swift 语言中优化值类型的重要特性,正确理解和使用它可以帮助你写出更高效和更可靠的 Swift 代码。

自定义一个Copy on Write类

其中isKnownUniquelyReferenced方法用于检测当时实例对象是否有引用,如果没有,则发生copy on write

class Storage {
    var data: [YourDataType] // 替换 YourDataType 为你需要存储的类型
    init(data: [YourDataType]) {
        self.data = data
    }
}

struct MyValueType {
    private var storage: Storage

    init(data: [YourDataType]) {
        storage = Storage(data: data)
    }
}

extension MyValueType {
    private mutating func copyOnWrite() {
        if !isKnownUniquelyReferenced(&storage) {
            storage = Storage(data: storage.data)
        }
    }

    mutating func append(_ item: YourDataType) {
        copyOnWrite()
        storage.data.append(item)
    }
}
相关推荐
程序猿看视界1 小时前
如何在 UniApp 中实现 iOS 版本更新检测
ios·uniapp·版本更新
dr李四维5 小时前
iOS构建版本以及Hbuilder打iOS的ipa包全流程
前端·笔记·ios·产品运营·产品经理·xcode
️ 邪神5 小时前
【Android、IOS、Flutter、鸿蒙、ReactNative 】自定义View
flutter·ios·鸿蒙·reactnative·anroid
比格丽巴格丽抱16 小时前
flutter项目苹果编译运行打包上线
flutter·ios
网络安全-老纪17 小时前
iOS应用网络安全之HTTPS
web安全·ios·https
今天啥也没干19 小时前
使用 Sparkle 实现 macOS 应用自定义更新弹窗
前端·javascript·swift
1024小神20 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
lzhdim21 小时前
iPhone 17 Air看点汇总:薄至6mm 刷新苹果轻薄纪录
ios·iphone
安和昂21 小时前
【iOS】知乎日报第四周总结
ios
yngsqq1 天前
037集——JoinEntities连接多段线polyline和圆弧arc(CAD—C#二次开发入门)
开发语言·c#·swift