簡體   English   中英

內存管理:保留具有弱var的循環,非保留循環與無主。 為什么?

[英]Memory management: retain cycle with weak var, non retain cycle with unowned. Why?

TL; DR

我有一個結構和一個類。 該結構具有對該類實例的引用,該對象具有一個捕獲該結構的閉包。 如果對該對象的引用是無主的,則它們似乎都被取消初始化。 如果對象的引用很弱,則它們相互保留。 為什么?

我有一個結構和一個可以互相引用的類,我試圖找出保留周期和方法來打破它們。 所以我在操場上玩了一下。

鑒於此代碼:

    struct A {
    unowned var b: B

    init(b: B) {
        self.b = b
    }

    func setup() {
        print("A setup")

        b.didSomethingClosure = {
            print("A: b did do something")
            self.printSomething()
        }
    }

    func printSomething() {
        print("A: A did do something")
    }
}

class B {

    var didSomethingClosure:(() -> Void)?

    func doSomething() {
        print("B: do something")
        didDoSomething()
    }

    func didDoSomething() {
        print("B: did something")
        if let closure = didSomethingClosure {
            closure()
        }
    }

    deinit {
        print("B: deinit")
    }
}


do {

    let b = B()
    let a = A(b: b)

    a.setup()
    b.doSomething()

    print("end do")
}

如果struct中的unowned var b: B聲明為unowned var b: B ,則釋放B對象。 如果我將代碼修改為weak var b: B? 然后b?.didSomethingClosure = ... ,保留B對象。 為什么?

我想問題是你在Playground運行它。 嘗試在真實的應用程序中運行它,你會看到B被解除分配

struct A {
    weak var b: B?

    init(b: B) {
        self.b = b
    }

    func setup() {
        print("A setup")

        b?.didSomethingClosure = {
            print("A: b did do something")
            self.printSomething()
        }
    }

    func printSomething() {
        print("A: A did do something")
    }
}

class B {

    var didSomethingClosure:(() -> Void)?

    func doSomething() {
        print("B: do something")
        didDoSomething()
    }

    func didDoSomething() {
        print("B: did something")
        if let closure = didSomethingClosure {
            closure()
        }
    }

    deinit {
        print("B: deinit")
    }
}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let b = B()
        let a = A(b: b)

        a.setup()
        b.doSomething()

        print("end do") // B is deallocated here
    }
}

暫無
暫無

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

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