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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/148872.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

用户的生命周期

用户生命周期是指用户在产品使用过程中的状态变化,一般分为5个阶段,分别为引入期、成长期、成熟期、沉默期和流失期。用户生命周期能够反映不同阶段用户的状态,可根据用户的不同状态进行针对性运营。运营中常说的拉新、促活、留存就是基于用户…

SLAM中提到的相机位姿到底指什么?

不小心又绕进去了,所以掰一下。 以我个人最直观的理解,假设无旋转,相机在世界坐标系的(5,0,0)^T的位置上,所谓“位姿”,应该反映相机的位置,所以相机位姿应该如下: Eigen::Matrix4d T Eigen::M…

上位机模块之halcon绘制ROI与获取ROI,在hsmartwindow实现

在上位机中通常需要使用到绘制ROI模块或者获取已经绘制好的ROI区域的参数&#xff0c;在这里通过使用hsmartwindow窗体控件进行对ROI的绘制和获取。 先上代码&#xff1a; /// <summary>/// 创建ROI/// </summary>/// <param name"Win">传入HSmar…

Centos7安装frps作内网穿透--实现外部访问家里群晖

实现在外可访问家用群晖 需要在外界访问家里的局域网设备&#xff0c;正常情况是需要有公网IP&#xff0c;而IPV4作为家用&#xff0c;运营商基本不给&#xff0c;除非钞能力&#xff0c;IPV6可以用&#xff0c;但是有缺陷&#xff0c;需要互访的两端都是IPV6才能访问。选择fr…

Mysql删除占用事务的线程

参考&#xff1a;https://www.jianshu.com/p/dd0291391188 产生原因&#xff1a;这个问题的原因是在mysql中产生了事务A&#xff0c;执行了修改的语句&#xff0c;比如&#xff1a; update t1 set aget18 where id1;此时事务并未进行提交&#xff0c;事务B开始运行&#xff0c…

kubernetes集群编排(10)

目录 prometheus监控 部署prometheus 部署nginx监控实例 部署prometheus-adapter prometheus监控 部署prometheus 创建项目仓库并上传镜像 [rootk8s2 helm]# vim prometheus-values.yaml alertmanager:alertmanagerSpec:image:repository: prometheus/alertmanagertag: v0.24.0…

知识解读:香港轻量云/云服务器/VPS性能差距解读

​  提起香港轻量云/云服务器/VPS 这三类&#xff0c;往往汇聚了中小企业和开发者等群体的讨论声音。当然&#xff0c;这跟它们本身产品定位有关&#xff0c;加上在初级配置这块价格上相差不大&#xff0c;也因此经常被拿来对比。 首先来简单了解一下最基础的区别&#xff1a…

Copliot:让你一秒变身网页达人的神奇助手

Copliot&#xff1a;一款能够帮助你快速理解网页内容的智能助手 你是否有过这样的经历&#xff0c;当你浏览网页时&#xff0c;遇到了一些你不太了解的内容&#xff0c;比如一些专业术语&#xff0c;一些复杂的概念&#xff0c;或者一些有趣的话题&#xff1f;你是否想要快速地…

Postman批量运行用例

近期在复习Postman的基础知识&#xff0c;在小破站上跟着百里老师系统复习了一遍&#xff0c;也做了一些笔记&#xff0c;希望可以给大家一点点启发。 一&#xff09;注意点 有上传文件的接口&#xff0c;需要做如下设置&#xff1a; 1、打开能读取外部文件的开关 2、把需要…

【IEEE】IF:10+, CCF|中科院1区TOP, 对国人友好,无需版面费

论文写作堪比西天取经&#xff0c;当我们经历“九九八十一难&#xff0c;取得真经“&#xff0c;还有最关键的一步&#xff0c;就是选刊发表。是“投石问路”&#xff0c;还是“投其所好”&#xff1f; 选刊有多重要&#xff0c;相信只要有过发表SCI经验的人都十分清楚。如果不…

登上CMMLU性能评测榜单第一 四大维度解码夸克自研大模型

11月14日&#xff0c;拥有千亿参数的夸克自研大模型正式发布&#xff0c;立刻占据CMMLU榜单第一名。夸克大模型将应用于通用搜索、医疗健康、教育学习、职场办公等多个场景。性能方面&#xff0c;其整体水平已经超过GPT-3.5&#xff0c;其中在写作、考试等部分场景中可以超过GP…

Android问题笔记四十五:解决SeekBar操作thumb周围产生的圆形阴影/灰色阴影/白色圆圈的解决办法

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列点击跳转>ChatGPT和AIGC &#x1f449;关于作者 专…

线性回归模型用于波士顿房价预测的(普通VSsklearn库方法)比较

努力是为了不平庸~ 学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰 线性回归是一种统计学习方法&#xff0c;用于建立一个线性模型来预测因变量与自变量之间的关系。它假设因变量与自变量之间存在线性关系&#xff0c;…

移远EC600U-CN开发板 11.15

制作一个简单UI: 1."端口设置"模块 *效果图 *代码 def backEvent(evt): #返回主界面code evt.get_code() if code lv.EVENT.CLICKED:lv.scr_load(mainInterface)def popUpEvent(evt): #弹窗提醒code evt.get_code()if code lv.EVENT.CL…

YOLOv8改进实战 | 更换主干网络Backbone(五)之2023最新轻量化主干网络VanillaNet,深度学习中极简主义的力量

前言 轻量化网络设计是一种针对移动设备等资源受限环境的深度学习模型设计方法。下面是一些常见的轻量化网络设计方法: 网络剪枝:移除神经网络中冗余的连接和参数,以达到模型压缩和加速的目的。分组卷积:将卷积操作分解为若干个较小的卷积操作,并将它们分别作用于输入的不…

HackTheBox-Starting Point--Tier 2---Unified

文章目录 一 Unified 测试过程1.1 打点1.2 权限获取1.3 权限提升 二 题目 一 Unified 测试过程 1.1 打点 1.端口扫描 nmap -sV -sC 2.访问8080端口 页面跳转到&#xff1a;https://10.129.96.149:8443/manage/account/login?redirect%2Fmanage   观察到版本号为unifi 6.4.5…

【LeetCode刷题-滑动窗口】--1423.可获得的最大点数

1423.可获得的最大点数 思路&#xff1a; 数组cardPoints的长度为n&#xff0c;由于只能从开头和末尾拿k张卡牌&#xff0c;所以最后剩下的必然是连续的n-k张卡牌&#xff0c;可以通过求出剩余卡牌点数之和的最小值&#xff0c;来求出拿走卡牌点数之和的最大值 算法&#xff…

antd中的form表单数据不更新

antd中的form表单 initialValue导致数据不更新问题 理解 &#xff1a; initialValue就是所谓的defaultValue,只会在第一次赋值的时候改变&#xff0c;却又有一些不同&#xff0c;因为 initialValue又会因其他改动而改变。 解决&#xff1a; form.resetFields();

NumLevels

NumLevels&#xff1a;输入参数&#xff0c;最大的金字塔层数。默认auto&#xff0c;范围【0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, auto】。 AngleStart&#xff1a;输入参数&#xff0c;输入匹配时的起始角度。默认-0.39&#xff0c;建议值【 -3.14, -1.57, -0.79, -0.39, -0.20,…

旅游业做服务预约小程序的效果

随着大环境放开&#xff0c;我国旅游业恢复了以往的热闹景象&#xff0c;人们仿佛看到了刺激性消费&#xff0c;各地景区的日接客量多且增加中&#xff0c;各旅行社又开始了忙碌的工作。 虽然目前大环境因素下&#xff0c;行业增长迅速&#xff0c;但也不得不面临一些固有的困…