The following playground example demonstrates two blocks of code, one of which creates a retain cycle and the other that does not. The only difference between the two code blocks is the placement of the guard clause. Can someone help explain how the top example creates a retain cycle since tempClosure
is not executed within the closure? Or could this be a swift bug?
import Foundation
class Example {
var closure: () -> () = { }
var innerClosure: () -> () = { }
func hasRetainCycle() {
var tempClosure: () -> () = { }
closure = { [weak self] in
guard let `self` = self else { return }
tempClosure = {
self.innerClosure = {
_ = self
}
}
}
closure()
}
func doesNotHaveRetainCycle() {
var tempClosure: () -> () = { }
closure = { [weak self] in
tempClosure = {
guard let `self` = self else { return }
self.innerClosure = {
_ = self
}
}
}
closure()
}
}
func showCycles() {
weak var hasRetainCycle: Example?
weak var doesNotHaveRetainCycle: Example?
autoreleasepool {
let example1 = Example()
example1.hasRetainCycle()
hasRetainCycle = example1
let example2 = Example()
example2.doesNotHaveRetainCycle()
doesNotHaveRetainCycle = example2
}
assert(hasRetainCycle != nil)
assert(doesNotHaveRetainCycle == nil)
}
showCycles()