Skip to content

Instantly share code, notes, and snippets.

@tilltue
Created June 3, 2021 16:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tilltue/09a3902957ddf1bfc88f4b671289fe54 to your computer and use it in GitHub Desktop.
Save tilltue/09a3902957ddf1bfc88f4b671289fe54 to your computer and use it in GitHub Desktop.
protocol Locking {
func lock()
func unlock()
}
protocol Synchronizing {
func sync<T>(execute: () throws -> T) rethrows -> T
}
extension Locking {
func sync<T>(execute: () throws -> T) rethrows -> T {
defer { unlock() }
lock()
return try execute()
}
}
extension NSLock: Locking, Synchronizing { }
final class LazyBox<T> {
private let compute: () -> T
private var _value: T?
private let _lock = NSLock()
init(_ compute: @escaping () -> T) {
self.compute = compute
}
var value: T {
if let _value = _value { return _value }
return _lock.sync {
if let _value = _value { return _value }
let v = compute()
_value = v
return v
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment