7

これが漏れない理由を誰か説明してもらえますか?

self内でキャプチャしているclosureため、2 つの強力なポインターが互いに指し合っているdeinitため、Person オブジェクトに対してメッセージが呼び出されることはありません。

まず、これは私のクラスPersonです:

class Person {
    var name: String
    init(name: String) { self.name = name }
    deinit { print("\(name) is being deinitialized") }
}

そして、これは私のViewControllerの実装です:

class ViewController: UIViewController {

    var john:Person?

    func callClosureFunction( closure:(name:Bool) -> () ) {
        closure(name: true)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        john = Person(name:"John")

        self.callClosureFunction { (name) in

            self.john?.name = "John Appleseed"
            self.john = nil

            // xcode prints - John Appleseed is being deinitialized
        }

    }

}

次のようにして問題を解決できると期待していました。

self.callClosureFunction { [weak self] (name) in ...

しかし、それは必要でもありませんでした。なんで?

4

3 に答える 3

0

私はクロージャー内で自己をキャプチャしているので、2 つの強力なポインターがお互いを指すことになります。したがって、Person オブジェクトに対して deinit メッセージを呼び出すべきではありません。

いいえ、クロージャから への強力なポインタが 1 つありますself。クロージャから への循環参照はありませんself。したがって、有向非環状グラフが得られますが、ARC にとっては問題ありません。

ただし、最初から、あなたの実験には欠陥があります。クロージャがキャプチャされたとしても、John Appleseed Personオブジェクトは依然としてdeinit. johnこのオブジェクトのライフサイクルは、からの参照のみに依存しますViewController。その参照を に設定すると、オブジェクトnilへの最後の参照が削除されるため、初期化が解除されます。John Appleseed

于 2016-08-10T16:20:43.910 に答える