简体   繁体   English

iOS ARC:使用 deinit 保留循环?

[英]iOS ARC: retain cycle with deinit?

iOS retain cycle: iOS 保留周期:

The typical example is A has B, B has A.典型的例子是A有B,B有A。

So what if A has B & C, B has C?那么如果A有B&C,B有C呢?

Is it still retain cycle?它仍然保持循环吗?

And is there a strong relationship that the deinit will not called by ARC when retain cycle exists?当保留周期存在时, ARC不会调用deinit是否存在很强的关系?

Here is the example code:这是示例代码:

class ViewModel{
    
    
    func doSth(){
        print("123")
    }
    
    
    deinit{
        print("ViewModel")
    }
}


class CustomView: UIView{
    
    var viewModel: ViewModel?
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        viewModel?.doSth()
    }
    
    
    deinit{
        print("CustomView")
    }
}


class ViewController: UIViewController {

    var viewModel = ViewModel()
    
    lazy var widget: CustomView = {
        let v = CustomView(frame: CGRect(origin: .zero, size: CGSize(width: 150, height: 150)))
        v.backgroundColor = UIColor.red
        v.viewModel = viewModel
        return v
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview(widget)
        
    }

    deinit{
        print("ViewController")
    }
}

when ViewController popped, three deinit method above are all called.ViewController弹出时,上面三个deinit方法都被调用。

So there is no retain cycle.所以没有保留周期。

Is it?是吗?

An easy way to figure out if you have a retain cycle is to draw a diagram.确定是否有保留周期的一种简单方法是绘制图表。 Use arrows for strong references, and dotted arrows for weak/unowned references.使用箭头表示强引用,虚线箭头表示弱/无主引用。

If you can follow the solid arrows from an object back to that same object, you have a retain cycle.如果您可以按照从 object 到同一个 object 的实线箭头,您有一个保留周期。

In your case, where A owns B and C, and B also owns C, there are 2 owning references to C, but no "backwards" strong references.在您的情况下,如果 A 拥有 B 和 C,并且 B 还拥有 C,则有 2 个拥有对 C 的引用,但没有“强引用”。 There is no way you get loop back to A or B, so there is no retain cycle.没有办法让你循环回到 A 或 B,所以没有保留循环。

Closures are another potential source of retain cycles that isn't obvious.闭包是另一个不明显的保留周期的潜在来源。 If you have an "escaping" closure that references "self", and you hold a strong reference to that closure, you have a retain cycle because you have an owning reference to the closure and the closure, through it's self reference, has a strong reference to you.如果你有一个引用“self”的“转义”闭包,并且你持有对该闭包的强引用,那么你就有一个保留循环,因为你有一个对闭包的拥有引用,而闭包通过它的self引用,有一个强引用参考你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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