By default, Swift guarantees thread safety for lazy initialization, ensuring that only one instance is created even in concurrent environments.
This is a wrong assumption. Initialization is not thread-safe, the initialization block can be called multiple times in a concurrent environment. For example:
class Example {
lazy var value: Int = {
print("Initializing value")
return 42
}()
}
let instance = Example()
DispatchQueue.global().async {
print("Thread 1: \(instance.value)")
}
DispatchQueue.global().async {
print("Thread 2: \(instance.value)")
}
"Initializing value" will be printed twice. See also this discussion - forums.swift.org/t/lazy-property-initialization-question/51085/8 for deeper understanding.