Now when a closure refers to self within its body the closure captures self, which means that it holds a strong reference back to the HTMLElement instance(see below). A strong reference cycle is created between the two. This means that the instance won't deinitialize (as shown below); however when I tried to replace self with heading (the instance) deinitilization did work which means that a strong reference cycle didn't exist. My understanding is that heading in this case is the same as self, since self is the instance itself. So why did the instance deinitialize when I replaced it with the instance 'heading'?
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = {
let defaultText = "some default text"
return "<\(heading.name)>\(heading.text ?? defaultText)</\(heading.name)>"
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
deinit {
print("\(name) is being deinitialized")
}
}
var heading = HTMLElement(name: "h1")
let defaultText = "some default text"
print(heading.asHTML())
// Prints "<h1>some default text</h1>”
heading = HTMLElement(name: "h4")
output:
< h1 > some default text < /h1 >
h1 is being deinitialized
Now if the closure was replaced as follows:
lazy var asHTML: () -> String = {
let defaultText = "some default text"
return "<\(self.name)>\(self.text ?? defaultText)</\(self.name)>"
}
the output would be:
< h1 > some default text < /h1 >