我正在寻找copy-on-write如何在swift中工作。而isKnownUniquelyReferenced
documentation有点困惑。特别是本节:
如果同时由多个线程访问作为对象传递的实例,则此函数仍可返回true。因此,您只能通过适当的线程同步从变异方法调用此函数。这将确保isKnownUniquelyReferenced(_ :)仅在存在一个访问者时才返回true,或者当存在竞争条件时,这已经是未定义的行为。
想象一下案例。
import Foundation
class StorageBuffer {
var field: Int = 1
init(_ field: Int) {
self.field = field
}
func copy() -> StorageBuffer {
return StorageBuffer(field)
}
}
struct Storage {
private var _buffer = StorageBuffer(1)
var field: Int {
get {
return _buffer.field
}
set {
if !isKnownUniquelyReferenced(&_buffer) {
_buffer = _buffer.copy()
}
_buffer.field = newValue
}
}
}
class StorageAware {
private var _storage = Storage()
private let _storageGuard = NSLock()
var storage: Storage {
_storageGuard.lock()
defer {
_storageGuard.unlock()
}
return _storage
}
}
由于真正的复制将在以后发生。是否足以同步吸气剂?在这种情况下,它是必要的还是结构本身是线程安全的? 在任何地方都有关于快速线程安全的完整文档吗?
答案 0 :(得分:1)
CoW结构与Int
一样线程安全,即它们不是原子的。因此,就像在修改Int时必须锁定并发访问一样,例如
lock.lock()
var myInt = _storedInt // lock required, not an atomic op
lock.unlock()
myInt += 1
复制 CoW结构时,您必须做同样的事情(尽管标记为_storage
的{{1}}本身没有被修改,因此,这表明-您需要锁定对var
的写访问权限。
但是,当您执行此操作时,_storage
保证如果引用是唯一的,则返回true。
错误:
isKnownUniquelyReferenced
右:
var myStorage = _storage // this can race
myStorage.value = 10
错误的版本显示了文档所谈论的种族。