Update, March 28, 2016: I now believe this more nuanced discussion is more useful. You should go read that post instead. It puts forth three rules for determining whether to use
!needs a guarantee that the view exists, so always use
strongto provide that guarantee
- If it’s possible the view isn’t part of the view hierarchy, use
?and appropriate optional-handling (optional binding/chaining) for safety
- If you don’t need a view anymore after removing it from the view hierarchy, use
weakso it gets removed from memory.
This post remains online for historical reference.
Xcode 6.3 beta adds
IBOutlet declarations like this by default:
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
I argue that this is wrong and unsafe. Making a
weak optional implicitly unwrapped (
!) is risky at best;
weak specifically means that this variable could, in principle, become
nil at any time, and combining it with
! seems to me like a recipe for disaster.
A fellow developer asked me yesterday, “the whole reason for declaring as
weak is that there at least one reference to the view (indirectly) via the view controller’s view hierarchy. Doesn’t that make you feel any better?”
I’d argue that the reason for declaring these references
weak is actually that when the view hierarchy goes away we don’t need them; and declaring them
weak means we don’t end up with references to dangling views which are no longer necessary.
The reason we can declare them
weak is that the views are retained, indirectly, via the view hierarchy. But that’s mostly a detail separate from our intent—our why in declaring the references as
That’s a stupidly pedantic point on my part, but I think it is helpful here to clarify why we’ve done this vs. the reason we can do it.
When I write the reasoning out like this, it’s clear (to me) that the reason view references are
weak is because their lifecycles aren’t intimately tied to the view controller.
We must decide whether we’re interested in the lifecycle of this object.
weak we’re explicitly saying “we aren’t tied to the lifecycle of this view, and if it goes away we don’t want to prevent that”.
! runs counter to that statement: it says implicitly “we expect this to practically always to be present, it’s just not set in
This is what makes this sort of declaration such a conflict in my mind: either we care (
!) or we don’t (
weak) about this object’s lifecycle.
(And in this particular case, I’m willing to bet there’s some pathological case, perhaps while the view is being destroyed, when this reference could be
nil but the view controller is still around. And if a notification or KVO event comes in at just the right time, and we try to update
activityIndicator based on that event, the whole app blows up trying to unwrap the optional.)