Swift的Copy on Write 简称CoW

news/2024/7/20 21:02:30 标签: swift, copy-on-write, ios

了解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)
    }
}

http://www.niftyadmin.cn/n/5187840.html

相关文章

【0234】PgBackendStatus 记录当前postgres进程的活动状态

1. 关于PgBackendStatus 每个存活的后端进场在共享内存中维护一个PgBackendStatus结构体,显示其当前活动状态。(结构体是根据BackendId分配的,但这并不重要。) 请注意: 进场状态收集器进程不参与、甚至不访问这些结构。 每个辅助进程还在共享内存中维护一个PgBackendStatu…

MySQL数据库干货_29——SQL注入

SQL注入 什么是SQL注入 所谓 SQL 注入,就是通过把含有 SQL 语句片段的参数插入到需要执行的 SQL 语句中,最终达到欺骗数据库服务器执行恶意操作的 SQL 命令。 SQL注入案例 /*** SQL注入测试类*/ public class SqlInjectTest {/*** 体现sql注入*/publ…

【你哥电力电子】从耦合电感到变压器

从耦合电感到变压器 2023年7月12日 dk 文章目录 从耦合电感到变压器1. 耦合电感1.1 一个等效1.2 自感、互感与漏感1.3 耦合系数2. 变压器3. 其他模型的推导方法3.1 T型等效电路3.2 其他等效电路4. 小结下链1. 耦合电感 1.1 一个等效 通电导线的周围会产生磁场,磁场可以通过…

【自动化测试】基于Selenium + Python的web自动化框架!

一、什么是Selenium? Selenium是一个基于浏览器的自动化工具,她提供了一种跨平台、跨浏览器的端到端的web自动化解决方案。Selenium主要包括三部分:Selenium IDE、Selenium WebDriver 和Selenium Grid:  1、Selenium IDE&…

物联网网关在工业行业的应用案例

物联网网关在工业行业的应用案例 随着物联网技术的不断发展,物联网网关在工业行业的应用越来越广泛。本文将介绍一个物联网网关在工业行业的应用案例,以期为相关领域的研究和实践提供借鉴和启示。 一、案例背景 某大型制造企业是一家全球知名的汽车制…

WordPress丸子小程序问题常见解决方案

WordPress丸子小程序问题常见解决方案 下载uniapp,导入项目。修改下图域名为自己的WP博客地址。(如下图) 发行微信小程序,如果显示不是项目所有者,请重新获取。 重新发行微信小程序,请打开微信开发者工具端…

docker 部署Redis集群(三主三从,以及扩容、缩容)

1:创建6个redis容器 docker run -d --name redis01 --net host --privilegedtrue -v /opt/redis/redis01:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381 docker run -d --name redis02 --net host --privilegedtrue -v /opt/redis/redis0…

【Dolphinscheduler3.1.1】二次开发本地启动项目(前端+后端)

背景说明 由于业务的定制化开发,需要对Dolphinscheduler进行二次开发,现将项目的启动步骤记录如下。 一、 基础软件安装(必装项请自行安装) Maven: v3.5,配阿里云仓库地址即可 Node: v16. MySQL (5.7系列) : 两者任选其一即可 JDK (1.8)…