簡體   English   中英

如何在 Swift 閉包中保留分配的實例?

[英]How box allocated instance is retained in Swift closure?

我試圖了解如何保留盒子分配的實例。 在這里的屏幕上,我們

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

沒關系,這是我所期望的,正如我所提到的,因為 -> Box 包裝Optional<A>而不創建新變量,它破壞了它

下一個例子也是合法的:

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

但是這個例子讓我有點困惑

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)

為什么在上一個示例中,當 scope 結束時,盒子分配的實例仍然被保留? scope 結束時是否有一些隱式復制?

這就是我所理解的正在發生的事情。

當你這樣做

var aa: A? = A()

只有selfaa有強引用,因此aa引用計數為 1。

當你這樣做

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

    closure = {
        print(aa)
    }
}

因為closure需要aa ,所以closure現在也有對aa的強引用,所以aa引用計數為 2。

當您從 scope 中取出 go 時, self不再指向aa ,並且其引用計數減少 1,但無法取消初始化aa ,因為它的引用計數不為 0,因為閉包強烈引用它。

關閉強弱ARC參考保持周期迅速

ARC 保持循環 swift 閉包 強弱引用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM