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)
    }
}
相关推荐
3***499627 分钟前
Swift Experience
开发语言·ios·swift
HarderCoder6 小时前
Swift 一个小型游戏对象模型渐进式设计(四)——类型擦除与 Existential:当泛型遇见动态派发
swift
HarderCoder6 小时前
Swift 一个小型游戏对象模型渐进式设计(五)——Swift 并发世界:把 Attackable 搬进 actor
swift
HarderCoder6 小时前
Swift 一个小型游戏对象模型渐进式设计(三)——把能力再抽象一层,写一套“伤害计算器”框架
swift
HarderCoder6 小时前
Swift 一个小型游戏对象模型渐进式设计(二)——协议与默认实现:如何写出不用继承的多态
swift
HarderCoder6 小时前
Swift 一个小型游戏对象模型渐进式设计(一)——继承机制解读:从基础类到防止重写
swift
疯笔码良7 小时前
【IOS开发】Objective-C 与 Swift 的对比
ios
HarderCoder7 小时前
Swift 中的迭代机制:Sequence、Collection 与 Iterator 完全拆解
swift
阿斌_bingyu70910 小时前
uniapp实现android/IOS消息推送
android·ios·uni-app
QuantumLeap丶12 小时前
《Flutter全栈开发实战指南:从零到高级》- 15 -本地数据存储
flutter·ios·dart