Reputation: 902
The Swift Programming Language guide has the following example:
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")
}
}
var paragraph:HTMLElement? = HTMLElement(name: "p", text: "hello, world")
println("\(paragraph!.asHTML())")
paragraph = nil
It was expected to print out the string in deinit() method, but it hadn't printed anything. It mean to me that the object is still alive, and has strong reference cycle with the closure. Does anyone get the same issue?
Upvotes: 3
Views: 2339
Reputation: 28688
Do this with weak capture instead of unowned
class HTMLElement {
let name: String
let text: String?
@lazy var asHTML: () -> String = {
[weak 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")
}
}
var paragraph:HTMLElement? = HTMLElement(name: "p", text: "hello, world")
println("\(paragraph!.asHTML())")
paragraph = nil
Upvotes: 2