为什么在UIView再次添加到父级之前不会调用deinit?

时间:2017-03-04 17:26:35

标签: swift memory memory-leaks swift3 deinit

我有一个UIView,它正在添加到UIViewController并且通常测试去初始化以确保我正在做正确的事情。但是当我没有将我的viewController中的变量设置为nil并且仅使用.removeFromSuperView()时,UIView中的deinit()方法将被调用,直到我再次添加UIView然后调用它。但是如果我使用removeFromSuperView()并将变量设置为nil,则立即调用deinit()。这是为什么?

这里是UIView()类:

class TestView: UIView {

    override init(frame: CGRect) {
        super.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
        print("init is happneing")
    }

    deinit {
        print("de init is happneing")
    }


    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

这里是父ViewController:

class MyViewController: UIViewController { 
 var tstview  : TestView?


  //adding the UIView by tapping on a button 
 @IBAction func addView(_ sender: UIButton) {

        let test = TestView()
        tstview = test
        tstview?.frame = CGRect(x: 50, y: 60, width: self.view.frame.width-100, height: self.view.frame.height-200)
        tstview?.backgroundColor = UIColor.white
        self.view.addSubview(tstview!)  
}

    override func viewDidLoad() {
       super.viewDidLoad()  
    }

    //removing UIView by touching elsewhere 
   override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
         tstview?.removeFromSuperview()
      //  tstview = nil

    }


}

1 个答案:

答案 0 :(得分:1)

当没有人引用该对象时,会调用

deinit。如果您未将tstview设置为nil,则您的MyViewController仍会引用它,因此deinit不会被调用。当您调用addView时,语句tstview = test最终会删除对旧视图的最后一个引用,从而触发取消初始化。

您可以在Swift documentation中详细了解取消初始化的概念。

如果您希望在分离视图后立即收到通知,请{。3}}。

class TestView: UIView {
    ...
    override func willMove(toSuperview newSuperview: UIView?) {
        if newSuperview == nil {
            print("removed from parent")
        }
    }
}