gpt4 book ai didi

ios - 原子属性包装器仅在声明为类时才有效,而不是结构体

转载 作者:行者123 更新时间:2023-12-04 11:14:15 26 4
gpt4 key购买 nike

我在 Swift 中创建了一个“锁”和一个使用该锁的 Atomic 属性包装器,用于我的 Swift 类,因为 Swift 缺少 ObjC 的 atomic属性属性。
当我在启用线程清理器的情况下运行我的测试时,它总是捕获使用我的 Atomic 属性包装器的属性上的数据竞争。
唯一有效的是将属性包装器的声明更改为一个类而不是一个结构体,这里的主要问题是:为什么它有效!
我已添加 print s 在属性包装器和锁定 init s 来跟踪创建的对象数量,它与 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

最佳答案

这个问题在这个 PR 中得到了回答:https://github.com/apple/swift-evolution/pull/1387
我认为这是那些真正解释它的台词💡

In Swift's formal memory access model, methods on a value types are considered to access the entire value, and so calling the wrappedValue getter formally reads the entire stored wrapper, while calling the setter of wrappedValue formally modifies the entire stored wrapper.


The wrapper's value will be loaded before the call towrappedValue.getter and written back after the call towrappedValue.setter. Therefore, synchronization within the wrappercannot provide atomic access to its own value.

关于ios - 原子属性包装器仅在声明为类时才有效,而不是结构体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67098381/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com