When writing the handler
closure of a UIAlertAction
, should the reference to self
be strong (the default), weak
, or unowned
?
There have been posts relevant to this topic (1, 2, 3, 4) but I honestly don't see how they help in this case.
Let's focus on this typical code:
func tappedQuitButton() {
let alert = UIAlertController(title: "Confirm quit", message: nil, preferredStyle: .ActionSheet)
let quitAction = UIAlertAction(title: "Quit", style: .Default) { (action) in
self.dismissViewControllerAnimated(true, completion: nil)
}
alert.addAction(quitAction)
let cancelAction = UIAlertAction(title: "Cancel", style: .Default) { (action) in
self.dismissViewControllerAnimated(true, completion: nil)
}
alert.addAction(cancelAction)
presentViewController(alert, animated: true, completion: nil)
}
This is a function inside a UIViewController
subclass, so self
is the view controller presenting the alert.
The documentation says:
Use a weak reference to avoid reference cycles whenever it is possible for that reference to have “no value” at some point in its life. If the reference will always have a value, use an unowned reference instead.
I may be blind, but I still don't see how this helps answering my question about UIAlertAction
.
In the above code, is it possible for self
to be nil at some point in its life? Yes. So I should mark self
as weak
.
But then again, I can't think of a plausible scenario where self
will be nil when the closure is called. So as far as that closure is concerned, self
will always have a value. So I should mark self
as unowned
.
So, again, how should self
be captured in a UIAlertAction's handler?
The key question to ask yourself is if your alert object is "owned" by self. In this case, it is not (because you declared let alert = ...
in the function body). So you do not need to create this as a weak or unowned reference.
If alert was a property of self, then it would be "owned" by self and that is when you would want to create a weak reference to self in the closure "owned" by the alert.