为什么"无主的自我"在关闭不能在Swift中正常工作?

时间:2014-06-18 16:50:15

标签: closures swift

Apple的Swift语言官方指南中的代码:

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 {
        println("\(name) is being deinitialized.")
    }
}

在闭包中使用带有unowned的捕获列表以避免保留周期。我们演示它:

var paragraph: HTMLElement? = HTMLElement(name: "p", text: "Hello, world!")
println(paragraph!.asHTML())        
paragraph = nil

结果应为

<p>Hello, world!</p>
p is being deinitialized.

最后一行很重要,因为它告诉我们paragraph预计会被取消初始化,但实际结果是

<p>Hello, world!</p>

最后一行没有出现。记忆泄露。这是官方指南中的原始代码。unowned没有正常工作? 所以我用weak而不是unowned来测试会发生什么:

...
    @lazy var asHTML: () -> String = {
        [weak self] in
        if let text = self?.text {
            return "<\(self?.name)>\(text)</\(self?.name)>"
        } else {
            return "<\(self?.name) />"
        }
    }
...

结果正是我们想要的。控制台显示p is being deinitialized. 我无法理解我的错误或指南中的原始代码是否出错?或者

1 个答案:

答案 0 :(得分:2)

编辑:现在已修复xcode 6 beta 3:

  

•无主类引用将不再有时保留它们   目标。 (16980445)


在昨天发布的Xcode 6 beta 2发行说明中,它提到:

  

•无主类引用有时会保留其目标。 (16980445)

Xcode 6 Beta 2中的已知问题。