someFunction(completion: { [weak self] in
self?.variable = self!.otherVariable
})
Is this always safe? I access the optional <
BEFORE CORRECTION:
I think others have answered the details of your question far better that I could.
But aside from learning. If you actually want your code to reliably work then its best to do as such:
someFunction(completion: { [weak self] in
guard let _ = self else{
print("self was nil. End of discussion")
return
}
print("we now have safely 'captured' a self, no need to worry about this issue")
self?.variable = self!.otherVariable
self!.someOthervariable = self!.otherVariable
}
AFTER CORRECTION.
Thanks to MartinR's explanation below I learnt a great deal.
Reading from this great post on closure capturing. I slavishly thought whenever you see something in brackets []
it means it's captured and its value doesn't change. But the only thing we're doing in the brackets is that we are weak
-ifying it and making it known to ourselves that it's value could become nil
. Had we done something like [x = self]
we would have successfully captured it but then still we'd have the problem of holding a strong pointer to self
itself and be creating a memory cycle. (It's interesting in the sense it's a very thin line from going to creating a memory cycle to creating a crash due to the value being deallocated because you weak-ified it).
So to conclude:
[capturedSelf = self]
creates memory cycle. Not good!
[weak self]
in guard let _ = self else{
return
}
(can lead to crash if you force the self
unwrap afterwards)guard let
is it utterly useless. Because the very next line, still self
can become nil
. Not good!
[weak self]
self?.method1()
(can lead to crash if you force self
unwrap afterwards. Would go through if self
is non-nil
. Would fail safely if self
is nil
.) This is what most likely what you want. This is Good!
[weak self] in
guard let strongSelf = self else{
return
}
Will fail safely if self
was deallocated or proceed if not nil
. But it kinda defeats the purpose, because you shouldn't need to communicate with self
when it removed it's own reference. I can't think of a good use case for this. This is likely useless!