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

Swift中如何证明超长字符串的写时复制?及代码地址问题解析

Swift字符串写时复制(Copy on Write)验证问题解析

问题描述

尝试验证Swift字符串的写时复制机制时,编写了如下代码:

func print(address o: UnsafeRawPointer) {
    print(o)
}

func longStringMemoryTest() {
    var longStr1 = "abcdefghijklmnopqr"
    var longStr2 = longStr1
    
    print(address: longStr1)
    print(address: longStr2)
    
    print("[append 'stu' to 'longStr2']")
    longStr2 += "stu"
    
    print(address: longStr1)
    print(address: longStr2)
    var test = "abcdefghijklmnopqr"
    print(address: test)
    print("[Fin]")
}

但控制台始终输出longStr1和longStr2的相同地址,即使两者内容已不同,无法观察到写时复制的效果。

核心原因:打印地址的方式错误

你当前的打印逻辑获取的是字符串结构体本身的地址(或无关内部指针),而非真正存储字符数据的堆内存地址。

Swift的String是值类型结构体,复制时仅复制结构体元数据,底层字符存储会被共享,直到发生写操作才会复制。但你没有正确获取到这个共享的存储地址,因此看不到写操作后的地址变化。

正确验证写时复制的方法

要观察写时复制的效果,需要通过withUTF8方法访问字符串底层UTF-8缓冲区的baseAddress,这才是字符数据的存储地址:

func printStorageAddress(of string: String) {
    string.withUTF8 { buffer in
        guard let address = buffer.baseAddress else {
            print("无法获取存储地址")
            return
        }
        print(address)
    }
}

func longStringMemoryTest() {
    var longStr1 = "abcdefghijklmnopqr"
    var longStr2 = longStr1
    
    print("初始状态下的底层存储地址:")
    printStorageAddress(of: longStr1)
    printStorageAddress(of: longStr2)
    
    print("\n[给longStr2追加'stu']")
    longStr2 += "stu"
    
    print("追加操作后的底层存储地址:")
    printStorageAddress(of: longStr1)
    printStorageAddress(of: longStr2)
    
    var test = "abcdefghijklmnopqr"
    print("\n新创建字符串的底层存储地址:")
    printStorageAddress(of: test)
    print("[Fin]")
}

预期输出说明

  • 初始状态:longStr1和longStr2的底层存储地址完全相同,说明两者共享同一块堆内存。
  • 追加操作后:longStr2的底层存储地址发生变化,而longStr1的地址保持不变,证明写操作触发了复制,两者不再共享存储。
  • 新创建的test地址可能与longStr1相同,这是Swift的字符串常量池优化,相同字面量会复用存储。

补充:小字符串优化的影响

Swift对短字符串有小字符串优化(Small String Optimization):当字符串长度足够短(通常是15个ASCII字符以内),字符数据会直接存储在String结构体内部,不会分配堆内存。这种情况下,即使执行写操作也不会触发堆内存的复制,但你的测试字符串长度已超过该阈值,无需担心此问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 04:01:56