The difference between Weak & Strong in Swift
A strong reference means that you want to “own” the object you are referencing with this property/variable. In contrast, with a weak reference you signify that you don’t want to have control over the object’s lifetime.
The simplest way to think about this is in terms of tree roots.
As long as the tree has one root anchoring it, it will not fall. The number of roots a tree has is similiar to its retain count. When the tree has no more roots reminaing, it will fall and the object will be destroyed. If the tree has at least one root holding it up, anyone can get/set properties and call methods on it.
A strong reference is like creating a new root for the tree, increasing it’s retain count by 1 and further ensuring it won’t be destroyed.
A weak reference is like observing the tree from afar. You can still perform all the same functions on it, but have no control over keeping it rooted and thereby ensuring it is not destroyed. If all its strong references are removed, you won’t be able to access the object.
Why create weak references?
Every strong reference and retained object increases your app’s memory usage and will affect performance. Weak references, when used properly, are a way to manage your app’s footprint.
The most frequent use cases of weak references in iOS are:
- Delegate properties, which are often referenced weakly to avoid retain cycles, and
- Subviews/controls of a view controller’s main view because those views are already strongly held by the main view.
A retain cycle is what happens when two objects both have strong references to each other. If 2 objects have strong references to each other, ARC will not generate the appropriate release message code on each instance since they are keeping each other alive.
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. Since weak variables can be nil if nobody holds a strong reference to them, the Swift compiler requires you to have weak variables as vars.
Weak and unowned references behave similarly but are NOT the same. Unowned references, like weak references, do not increase the retain count of the object being referred. However, in Swift, an unowned reference has the added benefit of not being an Optional.
Use a weak reference whenever it is valid for that reference to become nil at some point during its lifetime. Conversely, use an unowned reference when you know that the reference will never be nil once it has been set during initialization.