如果为a分配闭包,也会出现强引用循环 类实例的属性,该闭包的主体捕获 实例。
如果作为属性的闭包可以导致强保留周期,并且函数是根据Swift programming guide的一种闭包:
实际上,函数中引入的全局函数和嵌套函数 特殊情况的封闭
为什么不将闭包属性更改为实例方法会导致相同的保留周期?
实例方法是属于a实例的函数 特定的类,结构或枚举。
例如,按原样,下面的代码不会解除分配HTMLElement的实例,但是,如果我将asHTML
更改为函数而不是闭包表达式的名称,则HTMLElement
将被取消分配。
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = {
return "<\(self.name)>\(self.text ?? "")</\(self.name)>"
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
deinit {print("\(name) is being deinitialized")}
}
var headerTitle: HTMLElement? = HTMLElement(name: "h1", text: "Welcome")
print(headerTitle!.asHTML())
headerTitle = nil
调试器:
<h1>Welcome</h1>
更改为功能时:
func asHTML() -> String {
return "<\(self.name)>\(self.text ?? "")</\(self.name)>"
}
调试器:
<h1>Welcome</h1>
h1 is being deinitialized
答案 0 :(得分:1)
当你将一个闭包保存到一个实例变量时,闭包会导致一个保留周期,所以你有一个对闭包的强引用,然后闭包有一个对它的对象的强引用。
在第一个示例中,var asHTML是保存到HTMLElement
类中的实例变量的闭包。这意味着HTMLElement
实例保留了对闭包的强引用。
然后在你的闭包中你引用self
。这意味着闭包具有对定义它的对象的强烈引用(同样,HTMLElement
实例。)您已经创建了一个保留周期。
现在,如果你有一个你调用的函数asHTML()
,你就不会将该函数保存为某个对象。它是对象的实例方法。它提到了自我,因为它是自我的 PART 。因此没有保留周期。