【问题标题】:Swift retain cycle missing clarificationSwift 保留循环缺少说明
【发布时间】:2019-05-04 00:03:50
【问题描述】:

苹果有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")
    }

}

【问题讨论】:

    标签: ios swift iphone automatic-ref-counting


    【解决方案1】:

    实际上,您的示例不够人为。让我们让它更简单:

    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 is being deinitialized”。

    好的,但现在删除[unowned self] in。现在,当我们对其进行测试时,我们没有看到“C 正在被取消初始化”。我们有一个保留周期。

    所以是的,你有 self 保留一个引用 self 的函数,这是一个保留循环。你用unowned self打破循环是对的。

    (当然,在我的示例中,我考虑到您的lazy 使图片复杂化的方式。如果我们不说self.f()——也就是说,如果我们从不要求lazy var 进行初始化本身——那么当然,f 的初始化器 什么 并不重要:它永远不会被初始化,因此不会有保留周期。但这是一个极不可能的情况;如果你从来没有如果要初始化 lazy var,那么您将不会有 lazy var 开头。)

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多