繁体   English   中英

iOS ARC:使用 deinit 保留循环?

[英]iOS ARC: retain cycle with deinit?

iOS 保留周期:

典型的例子是A有B,B有A。

那么如果A有B&C,B有C呢?

它仍然保持循环吗?

当保留周期存在时, ARC不会调用deinit是否存在很强的关系?

这是示例代码:

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")
    }
}

ViewController弹出时,上面三个deinit方法都被调用。

所以没有保留周期。

是吗?

确定是否有保留周期的一种简单方法是绘制图表。 使用箭头表示强引用,虚线箭头表示弱/无主引用。

如果您可以按照从 object 到同一个 object 的实线箭头,您有一个保留周期。

在您的情况下,如果 A 拥有 B 和 C,并且 B 还拥有 C,则有 2 个拥有对 C 的引用,但没有“强引用”。 没有办法让你循环回到 A 或 B,所以没有保留循环。

闭包是另一个不明显的保留周期的潜在来源。 如果你有一个引用“self”的“转义”闭包,并且你持有对该闭包的强引用,那么你就有一个保留循环,因为你有一个对闭包的拥有引用,而闭包通过它的self引用,有一个强引用参考你。

暂无
暂无

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

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