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.
我无法理解我的错误或指南中的原始代码是否出错?或者
答案 0 :(得分:2)
编辑:现在已修复xcode 6 beta 3:
•无主类引用将不再有时保留它们 目标。 (16980445)
在昨天发布的Xcode 6 beta 2发行说明中,它提到:
•无主类引用有时会保留其目标。 (16980445)
Xcode 6 Beta 2中的已知问题。