引起懒加载多次的问题思考

iOS,Swift,Tips,Lazy

Posted by Karim on March 21, 2018

懒加载是为了保证属性只会初始化一次,同时在没有使用时,节能内存而使用的。苹果也非常推荐我们使用。但是今天在使用的时候,发现居然会懒加载了2次,为了更容易让别人看懂,我精炼了以下的代码,更好解释为什么会出现懒加载2次的情况。

class BViewController: UIViewController {

    lazy var bgView: UIView = {
        var bgView = UIView()
        view.addSubview(bgView)
        print(bgView)
        return bgView
    }()
    
    init(color :UIColor) {
        super.init(nibName: nil, bundle: nil)
        bgView.backgroundColor = color
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        bgView.frame = view.frame
        
    }
}

假设这时候AController通过init(color :UIColor)调用BController push进来

        let bvc = BViewController(color: .red)
        present(bvc, animated: true, completion: nil)

先来思考一下,bvc会是什么颜色?

答案是:黑色的(友情提示:Controller没有设置View颜色的时候,默认黑色)

这时候看一下打印信息:

<UIView: 0x7f97e0602fa0; frame = (0 0; 0 0); layer = <CALayer: 0x60000022c2e0>>
<UIView: 0x7f97e06098b0; frame = (0 0; 0 0); layer = <CALayer: 0x60000022be60>>

原来是因为bgView进行了两次懒加载,先讲下怎么解决这个问题,后面会详细分析原因,引起这个问题的原因其实就是因为这一行view.addSubview(bgView),此时把view.addSubview(bgView)放到viewDidLoad()再次运行,打印信息如下:

<UIView: 0x7fb94ac0e6b0; frame = (0 0; 0 0); layer = <CALayer: 0x604000224020>>

问题解决!
为了方便解释,我特地画了个图来解释第一次代码的生命周期:

换到第二个方式之后,就简单多了:

从这个问题,可以猜测Controller的view在生成的时候就会触发viewDidLoad,为了避免出现这样的问题,还是应该尽量少在Controller的初始化方法里进行操作。


请保持转载后文章内容的完整,以及文章出处。本人保留所有版权相关权利。

分享到: