我在 Swift 中创建了一个“锁”,并为我的 Swift 类创建了一个使用该锁的 Atomic 属性包装器,因为 Swift 缺少 ObjC 的atomic
property 属性。
当我在启用线程清理器的情况下运行测试时,它总是在使用我的 Atomic 属性包装器的属性上捕获数据竞争。
唯一有效的是将属性包装器的声明更改为类而不是结构,这里的主要问题是:为什么它有效!
我print
在属性包装器中添加了 s 和 lockinit
来跟踪创建的对象的数量,它与 struct/class 相同,尝试在另一个项目中重现问题,也没有用。但我会添加与问题相似的文件,并让我知道它为什么起作用的任何猜测。
锁
public class SwiftLock {
init() { }
public func sync<R>(execute: () throws -> R) rethrows -> R {
objc_sync_enter(self)
defer { objc_sync_exit(self) }
return try execute()
}
}
原子属性包装器
@propertyWrapper struct Atomic<Value> {
let lock: SwiftLock
var value: Value
init(wrappedValue: Value, lock: SwiftLock=SwiftLock()) {
self.value = wrappedValue
self.lock = lock
}
var wrappedValue: Value {
get {
lock.sync { value }
}
set {
lock.sync { value = newValue }
}
}
}
模型(数据竞争应该发生在publicVariable2
此处的属性上)
class Model {
@Atomic var publicVariable: TimeInterval = 0
@Atomic var publicVariable2: TimeInterval = 0
var sessionDuration: TimeInterval {
min(0, publicVariable - publicVariable2)
}
}
更新 1: 完整的 Xcode 项目:https ://drive.google.com/file/d/1IfAsOdHKOqfuOp-pSlP75FLF32iVraru/view?usp=sharing