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

标签 swift memory memory-leaks swift3 deinit

我有一个要添加到 UIViewController 的 UIView,并且通常会测试取消初始化以确保我做的事情是正确的。但是当我没有将我的 viewController 中的变量设置为 nil 并且只使用 .removeFromSuperView() 时,在我再次添加 UIView 然后调用它之前,不会调用 UIView 中的 deinit() 方法。但是,如果我使用 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")
    }
}

这是父 View Controller :

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

    }


}

最佳答案

deinit 在没有人引用该对象时被调用。如果您没有将 tstview 设置为 nil,您的 MyViewController 仍会引用它,因此不会调用 deinit。当您调用 addView 时,语句 tstview = test 最终删除了对旧 View 的最后一个引用,从而触发了析构器。

您可以在 Swift documentation 中阅读更多关于取消初始化的概念。 .


如果您想在 View 分离后立即收到通知,override willMove(toSuperview:)相反。

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

关于swift - 为什么在 UIView 再次添加到父级之前不调用 deinit?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42598996/

相关文章:

c++ - 如何在 C/C++ 中读/写任意位

c# - 异步递归。我的内存到底去哪儿了?

在自己的 malloc 函数中调用 printf 导致段错误

android - 在 android 中,当方向改变时,背景图像不会改变

delphi - TShellTreeView 内存泄漏

swift - 在 .linear 类型的 iCarousel 中快速自动滚动无限效果

ios - 在 cellForRowAtIndexPath 中重新排序 collectionViewCells 的目标

ios - 如何在 Swift 中以编程方式更改 UICollectionViewCell 大小?

ios - 如何通过按钮播放服务器中的视频

php - DOMDocument PHP 内存泄漏