为什么我在第二个例子中得到保留圈?
Why I get retain circle in the second 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
在第一个例子中,闭包被执行了一次,它returns一个字符串,并且那个字符串被赋值greeting
。没有关闭;什么都没有被捕获。这只是一个匿名函数。如果愿意,您可以去掉 self.
,就像在命名函数中一样。重点是 greeting
的类型是 String
.
在第二个例子中,greeting
是一个闭包值,它捕获了self
。由于 self
持有 greeting
而 greeting
持有 self
,因此存在循环。关键是greeting
的类型是() -> String
。这几乎肯定是一个错误,因为这不是 lazy
的用途。
(lazy
是 Swift 中的一个非常奇怪的功能,将其包含在语言中可能不是一个好主意。我尽量避免使用它。有几种微妙的方法用错了,被你咬了一点也不奇怪。)
为什么我们在第二个例子中得到了强引用圈,为什么我们在第一个例子中没有?
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
在第一个例子中,闭包被执行了一次,它returns一个字符串,并且那个字符串被赋值greeting
。没有关闭;什么都没有被捕获。这只是一个匿名函数。如果愿意,您可以去掉 self.
,就像在命名函数中一样。重点是 greeting
的类型是 String
.
在第二个例子中,greeting
是一个闭包值,它捕获了self
。由于 self
持有 greeting
而 greeting
持有 self
,因此存在循环。关键是greeting
的类型是() -> String
。这几乎肯定是一个错误,因为这不是 lazy
的用途。
(lazy
是 Swift 中的一个非常奇怪的功能,将其包含在语言中可能不是一个好主意。我尽量避免使用它。有几种微妙的方法用错了,被你咬了一点也不奇怪。)