Welcome to Lesson 2 of Swift Memory Management. You will discover a potential retain cycle that might occur while using the delegate pattern.
Why delegate should be weak var
Let us create a classic structure: the protocol, the delegator, and the delegate.
protocol SendDataDelegate {}
class SendingVC {
var delegate: SendDataDelegate?
deinit {
print("Delegator gone")
}
}
class ReceivingVC: SendDataDelegate {
lazy var sendingVC: SendingVC = {
let vc = SendingVC()
vc.delegate = self
return vc
}()
deinit {
print("Delegate gone")
}
}
Important: The closure init method is used with the
lazy
keyword from 3003_lazy_init_closures. You may not interact withself
while creating a brand new property since it is not initialized. However,lazy
allows since the property is initialized only afterself
has been created.
var receivingVC: ReceivingVC? = ReceivingVC()
receivingVC?.sendingVC // lazy born
Let us visualize the relationship.
There is a retain cycle. Even if you set recevingVC
as nil
, there is a reference count for both ReceivingVC
and SendingVC
from each other.
receivingVC = nil
// not deallocated
Make one of the relationships/references as weak
.
class SendingVC {
weak var delegate: SendDataDelegate?
...
}
However, as soon as you work with weak
which only applies to reference types, the compiler forces you to indicate the protocol as a different animal
protocol SendDataDelegate: class {}
Let us visualize the relationship.
Let us deallocate
receivingVC = nil
// "Delegate gone"
Notice that the SendingVC
object also has been deallocated since it no longer has a reference from the ReceivingVC
object.
- A
weak
reference allows the referencing object to becomingnil
(this happens automatically when the referenced object is deallocated) - Based on the rule above, the referencing object/variable must be
optional
5002_delegate_retention_cycle.playground
You've learned how to spot a retain cycle within the delegate pattern. You may wonder which variable should be set as weak
. The #1 rule is, a weak
property has a reference to a class object which more likely to stays longer, and eventually has greater importance. For example, if the SendingVC
object has a weak reference from the recevingVC
property, the object will be deallocated immediately since the reference count is zero.
In the following lesson, you will discover the pitfall of using closures due to the unique behavior you've learned in Chapter 3, 3004_capture_lists
Note: Learn Swift with Bob is available on Udemy. If you wish to receive a discount link, you may sign up here.