In yesterday’s installment of Understanding Swift Memory Management, you learned how weak and unowned references can be used to break a strong reference cycle. It’s time to take a closer look at what sets weak and unowned references apart from strong references. We also revisit weak and unowned references. What is the difference between weak and unowned references? When is it appropriate to choose an unowned reference over a weak reference?
Giving Automatic Reference Counting a Hand
I started this series by introducing you to Automatic Reference Counting. ARC helps manage the memory usage of the applications that run on your Apple devices. While it does its job well, it isn’t perfect. There are times that it needs your help.
For example, Automatic Reference Counting doesn’t know how to handle a strong reference cycle without your help. It applies a set of rules to make sure objects that are no longer needed are deallocated. Earlier in this series, you learned earlier that a strong reference cycle prevents objects that are no longer used from being deallocated.
In the previous article, I showed you how to a break strong reference cycle. By breaking a strong reference cycle, we help Automatic Reference Counting do its job. We can break a strong reference cycle using a weak or an unowned reference.
What Is the Difference Between Strong and Weak/Unowned References
The key difference between a strong and a weak or unowned reference is that a strong reference prevents the class instance it points to from being deallocated. That is very important to understand and remember.
Automatic Reference Counting keeps track of the number of strong references to a class instance. The class instance is not deallocated as long as at least one strong reference points to the class instance. That is, in a nutshell, what Automatic Reference Counting is about.
Weak and unowned references also point to class instances. The difference is that Automatic Reference Counting doesn’t take these references into account to determine if it’s safe to deallocate a class instance.
What Is the Difference Between Weak and Unowned References
Now that we know the difference between a strong and a weak or unowned reference, it’s time to find out what sets weak and unowned references apart. When should you choose an unowned reference over a weak reference?
In the previous article, we discovered that the
delegate property of the
UITableView class is defined as weak. After reading the previous article, you should understand why that is and why it’s not defined as a strong reference. Buy why is the
delegate property of
UITableView defined as weak? Why isn’t it defined as unowned?
A reference should be marked as weak if it’s possible that the class instance the reference points to is deallocated. This means that a weak reference can become
nil during its lifetime. This has several consequences that are important to keep in mind.
- Automatic Reference Counting automatically sets a weak reference to
nilwhen the class instance it points to is deallocated. But that’s a good thing. You don’t want to have a reference point to a class instance that no longer exists.
- Because ARC sets a weak reference to
nilwhen the class instance is deallocated, weak references always need to be declared as optionals. That makes sense. Right?
- This also implies that a weak reference should always be declared as a variable. We discussed this briefly in the previous article.
Unowned references differ in several aspects from weak references and they should not be used interchangeably. An unowned reference is always expected to have a value. Put differently, an unowned reference is always expected to point to a valid class instance. This means that it’s not necessary to declare an unowned reference as an optional.
Remember from the previous article that the
account property of the
Plan class isn’t declared as an optional. The only reason for defining the
account property of the
Plan class as unowned is to avoid a strong reference cycle.
Be warned, though. You are responsible for making sure an unowned reference always points to a valid class instance. If the class instance the unowned reference points to is deallocated, ARC doesn’t set the unowned reference to
nil. If you attempt to access the value of an unowned reference that no longer points to a valid class instance, a runtime error is thrown, terminating your application.
A Rule of Thumb
Apple recommends to use a weak reference if the class instance the reference points to has a shorter lifetime than the object that owns the reference. The
delegate property of the
UITableView class illustrates this.
Use an unowned reference if the reference is guaranteed to always have a value. An unowned reference is a good choice if the class instance the reference points to has a lifetime that exceeds or is equal to that of the object that owns the reference. Remember the example from the previous article. A plan should always have an account and an account should always have a plan. We only defined the
account property as unowned to avoid a strong reference cycle.
Even though memory management is no rocket science, it’s important to understand what strong, weak, and unowned references are, what sets them apart, and when it’s appropriate to use them. If anything in this series is unclear, drop a question in the comments below. You can also ping me on Twitter with feedback.<< How to Break a Strong Reference CycleHow to Use a Capture List to Break a Retain Cycle >>