属性 Wrapper @Lazy 变量线程安全吗?
Is Property Wrapper @Lazy variable thread safe?
我们现在有了一种创建惰性变量的新方法。它在 swift-evolution/proposals/0258-property-wrappers.md:
中描述
@propertyWrapper
enum Lazy<Value> {
case uninitialized(() -> Value)
case initialized(Value)
init(wrappedValue: @autoclosure @escaping () -> Value) {
self = .uninitialized(wrappedValue)
}
var wrappedValue: Value {
mutating get {
switch self {
case .uninitialized(let initializer):
let value = initializer()
self = .initialized(value)
return value
case .initialized(let value):
return value
}
}
set {
self = .initialized(newValue)
}
}
}
它是线程安全的实现吗?如果不是,如何重现非线程安全行为?
我有同样的问题,所以我通过编写一个小测试来测试它,该测试在 class 中的 属性 上使用这个 属性 包装器,然后尝试打印输出值(自纪元以来的时间)异步(10000 次)并且它在 wrappedValue getter 内的 'return value' 行上用 SIGABRT 爆炸。
我也试过 'getting' 不打印的值,我遇到了同样的问题。
所以我不得不说:不,它不是线程安全的。
编辑:我想补充一点,我在 https://www.onswiftwings.com/posts/atomic-property-wrapper/ 上做了同样的测试,那个确实是线程安全的,所以你可以用它作为基础来制作你自己的 'Lazy'那是线程安全的。
我们现在有了一种创建惰性变量的新方法。它在 swift-evolution/proposals/0258-property-wrappers.md:
中描述@propertyWrapper
enum Lazy<Value> {
case uninitialized(() -> Value)
case initialized(Value)
init(wrappedValue: @autoclosure @escaping () -> Value) {
self = .uninitialized(wrappedValue)
}
var wrappedValue: Value {
mutating get {
switch self {
case .uninitialized(let initializer):
let value = initializer()
self = .initialized(value)
return value
case .initialized(let value):
return value
}
}
set {
self = .initialized(newValue)
}
}
}
它是线程安全的实现吗?如果不是,如何重现非线程安全行为?
我有同样的问题,所以我通过编写一个小测试来测试它,该测试在 class 中的 属性 上使用这个 属性 包装器,然后尝试打印输出值(自纪元以来的时间)异步(10000 次)并且它在 wrappedValue getter 内的 'return value' 行上用 SIGABRT 爆炸。
我也试过 'getting' 不打印的值,我遇到了同样的问题。
所以我不得不说:不,它不是线程安全的。
编辑:我想补充一点,我在 https://www.onswiftwings.com/posts/atomic-property-wrapper/ 上做了同样的测试,那个确实是线程安全的,所以你可以用它作为基础来制作你自己的 'Lazy'那是线程安全的。