Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object is not deallocated when capturing by closures in Swift

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?

like image 916
LongNV Avatar asked Dec 14 '25 13:12

LongNV


1 Answers

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
like image 192
Joshua Weinberg Avatar answered Dec 19 '25 07:12

Joshua Weinberg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!