Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why I get retain circle in the second example?

Why do we get strong reference circle in the second example, why we did not in the first example?

class Test1 {
    var name: String = "Ted"
    lazy var greeting  = { return "Hello \(self.name)" }()
    deinit{print("goodby1")} // No retain cycle here ..
}
var v1:Test1? = Test1()
v1?.greeting
v1 = nil //prints goodby1, dealocation done

class Test {
    var name: String = "Mery"
    lazy var greeting = {return "Hello \(self.name)"}
    deinit{print("goodby")} //retain cycle here 

}
var v: Test? = Test()
v!.greeting
v = nil 
like image 337
Nalov Avatar asked Jan 21 '26 08:01

Nalov


1 Answers

In the first example, the closure is executed one time, it returns a String, and that String is assigned greeting. There is no closure; nothing is captured. This is just an anonymous function. If you like, you can get rid of the self., just like in a named function. The key point is that the type of greeting is String.

In the second example, greeting is a closure value, which captures self. Since self holds greeting and greeting holds self, there's a loop. The key point is that the type of greeting is () -> String. This is almost certainly a mistake, since this is not how lazy is intended to be used.

(lazy is a pretty weird feature in Swift, and was probably a bad idea to include in the langauge. I try to avoid it as much as possible. There are several subtle ways to use it incorrectly, so it's not surprising that it's bitten you.)

like image 105
Rob Napier Avatar answered Jan 24 '26 04:01

Rob Napier