There is already a standard expression of onceness. Unfortunately the standard Objective-C is unavailable in Swift (GCD dispatch_once
), but the standard Swift technique works fine, namely a property with a lazy define-and-call initializer.
Exactly how you do this depends on the level at which you want onceness to be enforced. In this example it's at the level of the class instance:
class MyClass {
// private part
private let completion : (() -> ())
private lazy var once : Void = {
self.completion()
}()
private func doCompletionOnce() {
_ = self.once
}
// public-facing part
init(completion:@escaping () -> ()) {
self.completion = completion
}
func doCompletion() {
self.doCompletionOnce()
}
}
And here we'll test it:
let c = MyClass() {
print("howdy")
}
c.doCompletion() // howdy
c.doCompletion()
let cc = MyClass() {
print("howdy2")
}
cc.doCompletion() // howdy2
cc.doCompletion()
If you promote the private stuff to the level of the class (using a static once
property), the completion can be performed only once in the lifetime of the entire program.