I often find myself worrying about retain cycles in my code. I feel like this is a common concern amongst others as well. I don't know about you, but it seems like I am constantly hearing "When am I supposed to use weak? And what the hell is this 'unowned' crap?!" The issue we find is that we know to use strong, weak, and unowned specifiers in our swift code to avoid retain cycles, but we don't quite know which specifier to use. Fortunately, I happen to know what they are AND when to use them! I hope this guide helps you to learn when and where to use them on your own.

Let's get started

ARC

ARC is a compile time feature that is Apple's version of automated memory management. It stands for Automatic Reference Counting. This means that it only frees up memory for objects when there are zero strong references to them.

Strong

Let's start off with what a strong reference is. It's essentially a normal reference (pointer and all), but it's special in it's own right in that it protects the referred object from getting deallocated by ARC by increasing it's retain count by 1. In essence, as long as anything has a strong reference to an object, it will not be deallocated. This is important to remember for later when I explain retain cycles and stuff.

Strong references are used almost everywhere in Swift. In fact, the declaration of a property is strong by default! Generally, we are safe to use strong references when the hierarchy relationships of objects are linear. When a hierarchy of strong references flow from parent to child, then it's always ok to use strong references.

Here is an example of strong references at play.

class Kraken { let tentacle = Tentacle() //strong reference to child. } class Tentacle { let sucker = Sucker() //strong reference to child } class Sucker {}

Kraken

Tentacle

Sucker

Kraken

Sucker

Here we have a linear hierarchy at play.has a strong reference to ainstance which has a strong reference to ainstance. The flow goes from Parent () all the way down to child ().

Similarly, in animation blocks, the reference hierarchy is similar as well:

UIView.animate(withDuration: 0.3) { self.view.alpha = 0.0 }

animateWithDuration

UIView

Sinceis a static method on, the closure here is the parent and self is the child.

What about when a child wants to reference a parent? Here is where we want to use weak and unowned references.

Weak and Unowned References

Weak

A weak reference is just a pointer to an object that doesn't protect the object from being deallocated by ARC. While strong references increase the retain count of an object by 1, weak references do not. In addition, weak references zero out the pointer to your object when it successfully deallocates. This ensures that when you access a weak reference, it will either be a valid object, or nil.

In Swift, all weak references are non-constant Optionals (think var vs. let ) because the reference can and will be mutated to nil when there is no longer anything holding a strong reference to it.

For example, this won't compile:

class Kraken { //let is a constant! All weak variables MUST be mutable. weak let tentacle = Tentacle() }

tentacle

let

Let

var

becauseis aconstant.constants by definition cannot be mutated at runtime. Since weak variables can be nil if nobody holds a strong reference to them, the Swift compiler requires you to have weak variables ass.