Here is my code:
protocol Delegate: NSObjectProtocol {}
class A: NSObject {
weak var delegate: Delegate!
override init() {
super.init()
}
func start() {
//synchronous------- print A: false
print("A:", delegate == nil)
//asynchronous------- print B: true Why is 'true'? How can do that not be released?
let time: NSTimeInterval = 1
let delay = dispatch_time(DISPATCH_TIME_NOW, Int64(time * Double(NSEC_PER_SEC)))
dispatch_after(delay, dispatch_get_main_queue()) {
print("B:", self.delegate == nil)
}
}
}
class B: NSObject, Delegate {
override init() {
super.init()
let a = A()
a.delegate = self
a.start()
}
}
I searched for other questions on stack overflow but I can't find something that can help me to fully understand this situation.
In class A you defined the delegate to be weak. This means that if no other object refers to the delegate object (instance of class B in your case), then this instance can be released.
In the beginning of the run, the instance of class B was reference by some object. In this class B you created class A instance, and assigned class B instance as its delegate. When you printed the delegate value, it was not nil.
Later, the instance of class B was not references any more by other object, beside the class A instance. Since class A instance referred to it as weak, its reference was not count, and instance A was released from memory. This is why when you printed the delegate value one second later it was nil.
Why to use weak? If you were not using weak, then class A instance would hold a reference to class B instance, and class B instance would hold a reference to class A instance. This way the reference counting of both instances will be greater than 0, and none of them could be freed!!! This will cause a memory leak. What you want is that if no other object is referencing the class B object it will be released from memory, and hence class A object could be release as well.