在封闭中保持周期迅速

时间:2019-05-23 04:35:44

标签: swift

我可以在Swift中看到很多保留周期的例子。但是,其中许多是不正确的,阅读文档并没有给出我可以遵循的非常简单的示例。

例如:

class Dog {
    func bark() {
        print ("YAP")
    }
}

var dog = Dog()
let doSomething = {
    dog.bark()
}

doSomething()

闭包是否会导致保留周期?我知道关闭会很快执行,但这不是问题。这会固有地导致保留周期吗?

2 个答案:

答案 0 :(得分:2)

您发布的程序中没有保留周期。

什么是保留周期?

将程序中的每个对象(包括每个闭包)视为有向图中的一个顶点。考虑从对象(或闭合)A到对象(或闭合)B的强烈引用,作为图中从A到B的边。

保留周期是图中的一个周期:一条路径,其中至少包含一条从顶点引回到自身的边(强参考)。

例如,典型的保留周期如下所示:

retain cycle from ViewController to View to Closure back to ViewController

视图控制器始终对其视图有很强的引用(如果已加载视图)。在此示例中,视图控制器创建了一个闭包。该闭包捕获了(强烈参考)视图控制器。然后,视图控制器将闭包存储在视图的一个属性中,从而创建一个保留周期。

什么是程序的保留图?

这是程序的保留图:

retain graph showing doSomething referencing dog

此图中没有保留周期。

答案 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)")
}