You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中修改存在副本的原数组时,Copy-on-Write会复制整个原数组吗?

Swift数组Copy-on-Write在修改结构体懒属性时的行为分析

问题背景

首先定义如下结构体:

struct Teste: Codable {
    let a: Int
    lazy var x: Int = {
        print("I just changed this Teste item")
        return a + 1000
    }()
}

假设有一个包含7.5亿个Teste实例的数组:

var hugeData: [Teste]

该数组是从云端获取后存储在单例中的数据。随后生成它的一个副本:

let see: [Teste] = hugeData.filter{ /* 过滤条件 */ }
// 仅包含4个元素,其中一个为hugeData[109333072]

当see仍存在时,执行如下代码:

let width = hugeData[109333072].x

核心疑问:此时是否会因see的存在,触发整个hugeData的Copy-on-Write全量复制?还是Swift的Copy-on-Write机制足够智能,仅复制体积很小的see?


演示验证代码

struct Teste: Codable {
    let a: Int
    lazy var x: Int = {
        print("I just calculated it", a + 1000)
        return a + 1000
    }()
}

print("yo")
var tt = [Teste(a:7), Teste(a:8), Teste(a:9)]
let tt2 = tt.filter{ $0.a > 8 }
print(tt)
print(tt2)
print("yes, still nil in tt2")
print("go..", tt[2].x)
print("go again..", tt[2].x)
print(tt)
print(tt2)
print("yes, copy on write was? applied to the original huge array")
print("ie YES, still nil in tt2")
let tt3 = tt.filter{ $0.a > 8 }
print(tt)
print(tt3)
print("yes, the set value seems to carry through to tt3")

运行结果

yo
[.Teste(a: 7, $__lazy_storage_$_x: nil), .Teste(a: 8, $__lazy_storage_$_x: nil), .Teste(a: 9, $__lazy_storage_$_x: nil)]
[.Teste(a: 9, $__lazy_storage_$_x: nil)]
yes, still nil in tt2
I just calculated it 1009
go.. 1009
go again.. 1009
[.Teste(a: 7, $__lazy_storage_$_x: nil), .Teste(a: 8, $__lazy_storage_$_x: nil), .Teste(a: 9, $__lazy_storage_$_x: Optional(1009))]
[.Teste(a: 9, $__lazy_storage_$_x: nil)]
yes, copy on write was? applied to the original huge array
ie YES, still nil in tt2
[.Teste(a: 7, $__lazy_storage_$_x: nil), .Teste(a: 8, $__lazy_storage_$_x: nil), .Teste(a: 9, $__lazy_storage_$_x: Optional(1009))]
[.Teste(a: 9, $__lazy_storage_$_x: Optional(1009))]
yes, the set value seems to carry through to tt3

结论

从演示结果可以明确:

  • 修改原数组hugeData中元素的懒属性时,不会触发整个大数组的Copy-on-Write全量复制。
  • 原数组元素的懒属性初始化后,之前生成的副本see(示例中的tt2)里的对应元素依然保持未初始化状态,说明Swift仅处理了被修改元素的存储,没有复制整个大数组。
  • 后续基于修改后的原数组生成的新副本,会包含已初始化的懒属性值,符合预期。

回到大规模数据场景的疑问:不会触发全量数组复制,Swift的Copy-on-Write机制足够智能,只会在必要时处理被修改的元素,无需复制7.5亿元素的大数组。

内容的提问来源于stack exchange,提问作者Fattie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 17:25:59