I am using Swift for a macOS application, Xcode is 12.5.1. Imagine I have the following code:
func performAsyncTask(completion: { [weak self] (error: Error?) in
self?.someProperty = 0.0
self?.someOtherProperty = 0.0
// Other similar statements follow
})
Is it good choice to change it to:
func performAsyncTask(completion: { [weak self] (error: Error?) in
guard let self = self else { return }
self.someProperty = 0.0
self.someOtherProperty = 0.0
// Other similar statements follow
})
I believe that the first implementation is better because self could become nil between the statements, so unwrapping at the beginning could be less clean. I hope an expert can bring me in the right direction. Thanks for your attention.
I believe that the first implementation is better because self could become nil between the statements
And that's why the second implementation is in fact better! If self
is not nil at the first statement, the first statement makes it so that self
couldn't become nil
between the statements. It retains self
exactly for the remainder of the block. This is called "the weak–strong dance".
guard let self = self else { return }
// ^^^^ this self is _strong_, not weak; it retains self
Edit: Note that in modern Swift it is sufficient to say
guard let self else { return }