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)
    }
}
相关推荐
2501_916008892 小时前
iOS 发布全流程详解,从开发到上架的流程与跨平台使用 开心上架 发布实战
android·macos·ios·小程序·uni-app·cocoa·iphone
非专业程序员4 小时前
iOS/Swift:深入理解iOS CoreText API
ios·swift
某柚啊5 小时前
iOS移动端H5键盘弹出时页面布局异常和滚动解决方案
前端·javascript·css·ios·html5
xingxing_F7 小时前
Swift Publisher for Mac 版面设计和编辑工具
开发语言·macos·swift
RollingPin16 小时前
iOS八股文之 RunLoop
ios·多线程·卡顿·ios面试·runloop·ios保活·ios八股文
2501_9160074717 小时前
iOS 混淆工具链实战,多工具组合完成 IPA 混淆与加固(iOS混淆|IPA加固|无源码混淆|App 防反编译)
android·ios·小程序·https·uni-app·iphone·webview
LinXunFeng18 小时前
Flutter webview 崩溃率上升怎么办?我的分析与解决方案
flutter·ios·webview
游戏开发爱好者819 小时前
FTP 抓包分析实战,命令、被动主动模式要点、FTPS 与 SFTP 区别及真机取证流程
运维·服务器·网络·ios·小程序·uni-app·iphone
Nick568321 小时前
Xcode16 避坑
ios
ii_best21 小时前
IOS/ 安卓开发工具按键精灵Sys.GetAppList 函数使用指南:轻松获取设备已安装 APP 列表
android·开发语言·ios·编辑器