我可以在Swift中看到很多保留周期的例子。但是,其中许多是不正确的,阅读文档并没有给出我可以遵循的非常简单的示例。
例如:
class Dog {
func bark() {
print ("YAP")
}
}
var dog = Dog()
let doSomething = {
dog.bark()
}
doSomething()
闭包是否会导致保留周期?我知道关闭会很快执行,但这不是问题。这会固有地导致保留周期吗?
答案 0 :(得分:2)
您发布的程序中没有保留周期。
将程序中的每个对象(包括每个闭包)视为有向图中的一个顶点。考虑从对象(或闭合)A到对象(或闭合)B的强烈引用,作为图中从A到B的边。
保留周期是图中的一个周期:一条路径,其中至少包含一条从顶点引回到自身的边(强参考)。
例如,典型的保留周期如下所示:
视图控制器始终对其视图有很强的引用(如果已加载视图)。在此示例中,视图控制器创建了一个闭包。该闭包捕获了(强烈参考)视图控制器。然后,视图控制器将闭包存储在视图的一个属性中,从而创建一个保留周期。
这是程序的保留图:
此图中没有保留周期。
答案 1 :(得分:0)
这是另一个在操场外运行的“示例”,用于展示带封闭口的保留周期:
class ClosureClassStrongRefCycle {
let str : String
lazy var printStr: () -> () = { // self is captured
print("\(self.str)")
}
init(str: String) {
self.str = str
}
deinit {
print("ClosureClassStrongRefCycle is being deallocated")
}
}
现在,当您像这样调用课程时:
do {
let myClassWithClosureStrongCycle = ClosureClassStrongRefCycle(str: "closure class strong cycle")
myClassWithClosureStrongCycle.printStr()
} // 'myClassWithClosureStrongCycle' is NEVER deallocated -> Strong reference cycle between this class and it's closure
ClosureClassStrongRefCycle
的实例保留其自身,因为其中的闭包保留了self
最后,如果您想摆脱保留周期,可以像这样添加unowned self
:
lazy var printStr: () -> () = { [unowned self] in // Unowned copy of self inside printStr
print("\(self.str)")
}