苹果有documentation that describes how retain cycles work in closures。这是他们不会造成保留周期的关闭示例。
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = {
[unowned self] in
if let text = self.text {
return "<\(self.name)>\(text)</\(self.name)>"
} else {
return "<\(self.name) />"
}
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
deinit {
print("\(name) is being deinitialized")
}
}
我偶尔喜欢将函数定义传递给回调,以尝试摆脱回调地狱的代码。
这个例子有些人为,但这会导致保留周期吗?将这样的函数分配给闭包是否会导致保留周期?
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = self.returnHTML
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
func returnHTML() -> String {
if let text = self.text {
return "<\(self.name)>\(text)</\(self.name)>"
} else {
return "<\(self.name) />"
}
}
deinit {
print("\(name) is being deinitialized")
}
}
答案 0 :(得分:2)
实际上,您的示例不够人为。让我们变得更简单:
class C {
lazy var f: () -> () = {
[unowned self] in
print(self)
}
init() {}
func doF() {
self.f()
}
deinit {
print("C is being deinitialized")
}
}
现在让我们对其进行测试:
let c = C()
c.doF()
结果:当c
超出范围时,我们看到“ C正在被初始化”。
好的,但是现在删除[unowned self] in
。现在,当我们对其进行测试时,我们不要看到“ C正在被初始化”。我们有一个保留周期。
是的,您有self
个保留引用self
的函数,这是一个保留周期。您可以通过unowned self
来打破循环。
(当然,在我的示例中,我考虑的是您的lazy
使图片复杂化的方式。如果我们不说self.f()
,也就是说,我们从不问{ {1}}进行自身初始化–当然,lazy var
的初始化器是什么没关系:它永远不会被初始化,所以不会有保留周期。极不可能的情况;如果您永远不会初始化f
,那么您就不会以lazy var
开始。)