【问题标题】:OSX deinit is not being called after dismissing view controller关闭视图控制器后未调用 OSX deinit
【发布时间】:2017-10-06 08:37:44
【问题描述】:

在“deinit”方法中没有命中断点时存在主题。解决方案是将可执行代码放入其中。试过了 - 没用。

从第一个窗口发起ViewController的代码:

    let vc = self.storyboard?.instantiateController(withIdentifier: "testwindow") as! NSViewController
    self.presentViewControllerAsModalWindow(vc)

它会打开一个带有按钮的新窗口,单击该按钮会调用以下代码

    dismissViewController(self)

这里是带断点的 deinit 代码。

僵尸对象未在方案中启用。

如果在弹出窗口再次出现时重新使用视图控制器,那将不是问题,但是每次都会创建视图控制器的新实例。

有什么办法可以确保对象被销毁?

【问题讨论】:

  • 我想说你仍然有一个或多个强有力的参考指向你的 VC。这样它就不会在调用dismiss时被取消初始化。
  • @dvdblk 除了我提到的之外,我没有任何额外的代码。那是一个测试项目。故事板是否有可能以某种方式阻止其发布?
  • @Ruzard 调用dismissViewController(self) 位于哪个类中?视图的呈现者或呈现的视图。该方法的文档指出“要关闭模式窗口,请在 self(呈现视图控制器)上调用 dismissViewController(_:) 方法。”。这可能是您代码中的潜在问题。
  • @RohanBhale 显然我错过了那条线。你说得对。谢谢你。如果您可以将其作为单独的答案发布 - 我会将其标记为解决方案并提供赏金。
  • @Ruzard 请检查我的答案。

标签: swift macos memory-leaks deinit


【解决方案1】:

Apple 用于关闭使用presentViewControllerAsModalWindow() 呈现的控制器的文档指出“要关闭模式窗口,请在自身(呈现视图控制器)上调用dismissViewController(_:) 方法。”。因此,您可能会从呈现的控制器本身中解散呈现的控制器。从呈现视图控制器调用dismiss会有所帮助。

【讨论】:

    【解决方案2】:

    只是尝试按照您在每个 viewController 中使用按钮的相同代码复制此代码并成功命中断点,并将 var num 从 0 (viewDidLoad) 更改为 1 并在 deInit 中更改回 0:

    您正在尝试什么?当你点击dismiss时,是不是调用了deinit方法?

    // 主视图控制器

    @IBAction func letsGo(_ sender: UIButton) {
            if let vc = storyboard?.instantiateViewController(withIdentifier: "second") as? SecondViewController {
                self.present(vc, animated: true, completion: nil)
            }
        }
    

    // 第二个视图控制器

    class SecondViewController: UIViewController {
    
        var num = 0
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // Do any additional setup after loading the view.
            num += 1
            print("\(num)")
        }
    
        @IBAction func dismissTheHype(_ sender: UIButton) {
            self.dismiss(animated: true, completion: nil)
        }
    
        deinit {
            print("deiniting")
    
            num -= 1
            doNothing()
            print("printing number \(num)")
        }
    
        func doNothing(){
            var number = 4
            number += 1
            print("\(number) times")
        }
    }
    

    【讨论】:

    • 我试过你的代码 - 是的,它确实按预期工作。但是我不是为 iOS 做的。我想存在架构上的差异。
    • 对了,OP用的是presentViewControllerAsModalWindow,也就是模态的。
    猜你喜欢
    • 2016-07-05
    • 2018-12-07
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    • 2018-05-24
    • 2019-08-08
    • 1970-01-01
    • 2016-03-22
    相关资源
    最近更新 更多