We now have a new way to make a lazy variable. It is described in 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)
}
}
}
Is it a thread safe implementation? If not, how to reproduce non thread safe behavior?
The Lazy<T> instance is not thread safe; if the instance is accessed from multiple threads, its behavior is undefined. Use this mode only when high performance is crucial and the Lazy<T> instance is guaranteed never to be initialized from more than one thread.
Another problem is that lazy var is not thread-safe which means the closure can get executed multiple times due to accesses from different threads.
Property Wrappers in Swift allow you to extract common logic in a distinct wrapper object. This new technique appeared at WWDC 2019 and first became available in Swift 5. It's a neat addition to the Swift library that allows removing much boilerplate code, which we probably all have written in our projects.
You can't make it lazy let because lazy properties must always be variables. Because the actual value is created by evaluation, you need to declare its data type up front. In the case of the code above, that means declaring the property as Int .
I had the same question, so I tested it out by writing a small test that uses this property wrapper on a property in a class, and then try to print out the value (time since epoch) async (10000 times) and it blew up with a SIGABRT on the 'return value' line inside the getter of wrappedValue.
I also tried just 'getting' the value without printing, and I had the same issue.
So I would have to say: no, it is not thread safe.
EDIT: I'd like to add that I did the same test on https://www.onswiftwings.com/posts/atomic-property-wrapper/ and that one is indeed thread safe, so you could use that as a base to make your own 'Lazy' that is thread safe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With