简体   繁体   中英

How box allocated instance is retained in Swift closure?

I'm trying to understand how box allocated instance are retained. On the screen here, we

class A {
    deinit {
        print("deleted")
    }
}

var closure: (() -> Void)!

if true {
    var aa: A? = A()
    closure = {
        // Box wraps Optional<A> without creating new variable, it destroyed cuz it follows outer changes to variable
        print(aa)
    }

    aa = nil
}

closure() // output: deleted; nil

That's okey, this is what I expect expect, as i mentioned because -> Box wraps Optional<A> without creating new variable, it destroyed cuz it

Next example legit too:

class A {
    deinit {
        print("deleted")
    }
}

var closure: (() -> Void)!

if true {
    var aa: A? = A()
    closure = { [weak aa] in
        // creating a weak variable, that ends up when scope is over. That's okay
        print(aa)
    }

}

closure() // output: deleted; nil

But this example, get me confused a bit

class A {
    deinit {
        print("deleted")
    }
}

var closure: (() -> Void)!

if true {
    var aa: A? = A()
    closure = {
        // Box retains Optional<A> without creating new variable after if scope end, it doesn't destroyed? But why?
        print(aa)
    }
}

closure() // output: Optional(__lldb_expr_27.A)

Why in last example when scope is over, box allocated instance still gets retained? Is there some implicit copying when scope is over?

This is what I understand is happening.

When you do

var aa: A? = A()

Only self has a strong reference to aa so aa reference count is 1.

When you do

if true {
    var aa: A? = A()

    closure = {
        print(aa)
    }
}

Because closure requires aa , closure also has a strong reference to aa now so aa reference count is 2.

When you go out of scope, self no longer points to aa and its reference count decreases by 1 but aa cannot be deinitialized because its reference count is not 0 since closure strongly references it.

关闭强弱ARC参考保持周期迅速

ARC 保持循环 swift 闭包 强弱引用

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM