Swift Weak vs Unowned
When to use Weak and when to use Unowned, by examples.
Problem
In a previous article, we discussed how Automatic Reference Counting (ARC) is used to manage memory usage in an iOS application. However, in some cases, ARC is not able to release objects from memory due to retain cycles.
Retain Cycle is the case when 2 objects have a strong reference to each other and are retained, make it impossible for ARC to release those object from the memory and cause what we call a “Memory Leak”.
Solution
By default whenever we declare a variable it is considered as “strong’’,
to avoid retain cycles we should declare those variable as “weak” or “unowned”. This article main focus is not about handling memory management, if you are not familiar with that topic read the previous article.
Our focus will be on when to use weak and when it is better to use unowned by real-world examples.
Weak vs Unowned
According to Apple’s Documentation:
Define a capture in a closure as an unowned reference when the closure and the instance it captures will always refer to each other, and will always be deallocated at the same time.
Conversely, define a capture as a weak reference when the captured reference may become
nil
at some point in the future. Weak references are always of an optional type, and automatically becomenil
when the instance they reference is deallocated. This enables you to check for their existence within the closure’s body.
The main difference between weak and unowned is that weak
is optional while unowned
is non-optional.
By declaring it weak
you get to handle the case that it might be nil inside the closure at some point. If you try to access an unowned
variable that happens to be nil, it will crash the whole program. So only use unowned
when you are positive that variable will always be around while the closure is around.
Unowned
You might have heard the above a lot before, but when you should really be positive that the variable will always be around when the closure is around so you can use unowned
without any worries?
Let us see the example below:
In the example above, there is no way that the closure will live more than the ViewController, in that case, you can be confident to use unowned
.
Weak
Now in the following example, let us see when you should use weak
to avoid crashes:
In the above case, you can never be sure that the ViewController will live more than the closure since the network call response can occur after closing the controller, so you should definitely use weak
as an optional to avoid crashes.
If we can use weak
in all cases, then why to use unowned
and take a risk of the app crashing? The answer is simple, according to apple:
If the captured reference will never become
nil
, it should always be captured as an unowned reference, rather than a weak reference.
Unowned is faster and allows for immutability and non-optionality.
If you don’t need weak, don’t use it.
Conclusion
To avoid memory leaks we should declare variables as weak or unowned instead of the default implementation which is strong.
However the key difference between them is that weak is an optional type , while unowned is not, so we should only use unowned when we are 100% sure that the closure have the same lifetime of the variable, so the closure will be reachable only until the variable is reachable.
References
Read my previous article about Avoiding Memory Leaks by Examples