String = {
[unowned self] (index: Int, stringToProcess: String) -> String in
// closure body goes here
}
如果闭包没有指定参数列表或者返回类型(可以通过上下文推断),那么占有列表放在闭包开始的地方,跟着是关键字in:
lazy var someClosure: () -> String = {
[unowned self] in
// closure body goes here
}
前面提到的HTMLElement例子中,非持有引用是正确的解决强引用的方法。这样编码HTMLElement类来避免强引用环:
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")
}
}
上面的HTMLElement实现和之前的实现相同,只是多了占有列表。这里,占有列表是[unowned self],代表“用无主引用而不是强引用来占有self”。
和之前一样,我们可以创建并打印HTMLElement实例:
var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
println(paragraph!.asTHML())
// 打印"<p>hello, world</p>"
引用关系如下图
这一次,闭包以无主引用的形式占有self,并不会持有HTMLElement实例的强引用。如果赋值paragraph为nil,HTMLElement实例将会被销毁,并能看到它的deinitializer打印的消息。
paragraph = nil
// 打印"p is being deinitialized"