Should self be captured as strong in a UIAlertAction's handler?

Eric picture Eric · Jan 21, 2016 · Viewed 7.6k times · Source

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?

Answer

Good Doug picture Good Doug · Jan 21, 2016

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.