Swift中闭包的强引用周期

Gio*_*nni 3 swift

我正在阅读文档(关于"自动引用计数"一节"闭包的强引用周期"一章),我似乎无法弄清楚在定义一个类时的情况,我应该在其中保留一个强引用self(在一个属性的闭包中的那个类的实例.捕获列表似乎总是避免内存泄漏的最佳解决方案,我真的想不出任何我应该保持强大的参考周期的场景.

以下是文档提供的示例:

class HTMLElement {

    let name: String
    let text: String?

    // Without Capture List 
    @lazy var asHTML: () -> String = {
        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 {
        println("\(name) is being deinitialized")
    }

}
Run Code Online (Sandbox Code Playgroud)
class HTMLElement {

    let name: String
    let text: String?

    // With Capture List
    @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 {
        println("\(name) is being deinitialized")
    }

}
Run Code Online (Sandbox Code Playgroud)

Ben*_*itz 5

如果要创建一个由生命周期可能与self不匹配的对象或函数执行的闭包,则需要保留对self的强引用.

例如:

class A {
    func do() {
        dispatch_async(dispatch_get_global_queue(0, 0)) {
            println("I printed \(self) some time in the future.")
        }
    }
}

var a : A? = A()
a.do()
a = nil // <<<
Run Code Online (Sandbox Code Playgroud)

在箭头处,主函数体将释放其对新创建的A实例的最后一个引用,但是调度队列需要保持它,直到闭包执行完毕.