swift - 如何在 Swift 中证明 String 类型的 "copy-on-write"

标签 swift string copy-on-write

正如标题所说,我试图证明自己 Swift 中的 String 支持 COW(copy on write)。但我找不到证据。在尝试以下代码后,我在 Array 和 Dictionary 上证明了 COW:

func address(of object: UnsafeRawPointer) -> String {
    let addr = Int(bitPattern: object)
    return String(format: "%p", addr)
}

var xArray = [20, 30, 40, 50, 60]
var yArray = xArray

// These two addresses were the same
address(of: xArray) 
address(of: yArray)

yArray[0] = 200
// The address of yArray got changed
address(of: yArray)

但是对于 String 类型,它是行不通的。

var xString = "Hello World"
var yString = xString

// These two addresses were different
address(of: xString)
address(of: yString)

我从官方 Swift 代码库中转储了测试函数。

func _rawIdentifier(s: String) -> (UInt, UInt) {
    let tripe = unsafeBitCast(s, to: (UInt, UInt, UInt).self)
    let minusCount = (tripe.0, tripe.2)
    return minusCount
}

但是这个函数似乎只转换指向的实际值而不是地址。因此,两个具有相同值的不同字符串变量将具有相同的 rawIdentifier。仍然无法向我证明 COW。

var xString = "Hello World"
var yString = "Hello" + " World" 

// These two rawIdentifiers were the same
_rawIdentifier(s: xString)
_rawIdentifier(s: yString)

那么 COW 在 Swift 中是如何处理 String 类型的呢?

最佳答案

编译器只为两者创建一个存储 "Hello World""Hello" + " World"

您可以通过检查汇编代码来验证这一点 获得自

swiftc -emit-assembly cow.swift

which defines only a single string literal

    .section    __TEXT,__cstring,cstring_literals
L___unnamed_1:
    .asciz  "Hello World"

As soon as the string is mutated, the address of the string storage buffer (the first member of that "magic" tuple, actually _baseAddress of struct _StringCore, defined in StringCore.swift) changes:

var xString = "Hello World"
var yString = "Hello" + " World"

print(_rawIdentifier(s: xString)) // (4300325536, 0)
print(_rawIdentifier(s: yString)) // (4300325536, 0)

yString.append("!")
print(_rawIdentifier(s: yString)) // (4322384560, 4322384528)

为什么你的

func address(of object: UnsafeRawPointer) -> String

函数显示 xArrayyArray 的相同值,但是 不适用于 xStringyString 吗?

数组传递给采用不安全指针的函数 第一个数组元素的地址,两者都相同 阵列,如果他们共享存储。

将一个字符串传递给一个接受不安全指针的函数传递一个 指向字符串的临时 UTF-8 表示形式的指针。 该地址在每次调用中可以不同,即使对于相同的字符串也是如此。

此行为记录在“Using Swift with Cocoa and Objective-C"UnsafePointer<T> 参数引用,但显然 UnsafeRawPointer 参数的工作方式相同。

关于swift - 如何在 Swift 中证明 String 类型的 "copy-on-write",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46747363/

相关文章:

ios - Swift:实现可拖动的 UIImageView 需要哪些方法?

swift - 更改另一个模块中 var 的初始值

python - 如何在 python 中拆分具有多个条件的字符串?

c - 如何实现calloc

redis - 启动 celery worker 服务器时无法诊断 MISCONF redis 问题

ios - 导航下方有空白

c# - 多次在字符串中添加一个字符串

python - 获取 IndexError : string index out of range in python

python - Python 中的对象回滚、写时复制、版本化代理等

ios - 按键中对象的属性对字典进行排序/过滤