TL;DR
I have a struct and a class. The struct has a reference to an instance of the class, and the object has a closure that captures the struct. If the reference to the object is unowned it seems that both of them get deinitialised. If the reference to the object is weak they retain each other. Why?
I have a struct and a class that may reference to each other and I was trying to figure out retain cycles and ways to break them. So I played a little bit with playground.
Given this code:
struct A {
unowned var b: B
init(b: B) {
self.b = b
}
func setup() {
print("A setup")
b.didSomethingClosure = {
print("A: b did do something")
self.printSomething()
}
}
func printSomething() {
print("A: A did do something")
}
}
class B {
var didSomethingClosure:(() -> Void)?
func doSomething() {
print("B: do something")
didDoSomething()
}
func didDoSomething() {
print("B: did something")
if let closure = didSomethingClosure {
closure()
}
}
deinit {
print("B: deinit")
}
}
do {
let b = B()
let a = A(b: b)
a.setup()
b.doSomething()
print("end do")
}
If var b in the struct is declared as unowned var b: B
, the B object is released. If I modify the code to weak var b: B?
and then b?.didSomethingClosure = ...
, the B object is retained. Why?