子视图控制器上未调用deinit方法

3

我有一个父视图控制器,通过子视图控制器的类方法插入子视图控制器。这个方法非常好用。

class func insertIntoController(parentController: UIViewController, parentView: UIView) -> VideoDoorbellLiveView? {
    guard let liveViewController = parentController.storyboard?.instantiateViewControllerWithIdentifier(liveViewIdentifier) as? VideoDoorbellLiveView else { return nil }

    liveViewController.view.translatesAutoresizingMaskIntoConstraints = false
    parentController.addChildViewController(liveViewController)
    parentView.addSubview(liveViewController.view)

    let views = ["view": liveViewController.view]
    var constraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[view]-0-|", options: NSLayoutFormatOptions.DirectionLeadingToTrailing, metrics: nil, views: views)
    constraints.appendContentsOf(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[view]-0-|", options: NSLayoutFormatOptions.DirectionLeadingToTrailing, metrics: nil, views: views))
    parentView.addConstraints(constraints)

    liveViewController.didMoveToParentViewController(parentController)

    return liveViewController
}

父级组件确保控制器存在并设置一些字符串变量等。非常好用。

    guard let controller = VideoDoorbellLiveView.insertIntoController(self, parentView: liveView) else { return }
    liveViewController = controller // liveViewController is an optional instance variable

我的问题是当父视图控制器(parentVC)消失时(deinit被调用),子视图控制器(child VC)的deinit没有被调用。

有什么想法吗?childVC中没有parentVC的引用。

我甚至尝试在parentVC中做了以下操作,但不能保证成功:

deinit {
    if let liveViewController = liveViewController {
        liveViewController.removeFromParentViewController()
    }
}

子视图控制器中可能存在保留循环。 - dan
那是我的第一个想法。检查了每个闭包,我们每次都使用 [weak self]。不确定还要寻找什么 :( - Aaron Bratcher
使用Instruments,如果存在泄漏,它将精确定位。 - matt
另外,我有点担心你的 liveViewController = controller。你不应该保留第二个持久引用到你的子视图控制器。你已经有一个(在 childViewControllers 数组中),这是你访问子视图控制器的唯一方式。至少,将此引用设置为弱引用,但最好根本不要保留它。 - matt
@matt 最近的引用是为了解决子VC不消失的问题。另外,由于parentVC正在调用其deinit,那么我应该能够假定它的实例变量也会消失。 - Aaron Bratcher
1个回答

0

对我来说,我遇到了一个保留循环并需要将弱引用传递给父视图控制器中的 Firebase 观察者,然后两者都调用了 deinit:

    func observeFeatureChanged(){
    microbeRef.queryOrdered(byChild: Nodes.TIMESTAMP)
        .observe(.childChanged) { [weak self] (dataSnapshot) in
            if let featureDic = dataSnapshot.value as? [String: Any]{
                let featureName = dataSnapshot.key
                if let index = self?.featureNames.firstIndex(of: featureName){
                    self?.featureNames[index] = featureName
                    self?.featureDictionaries[index] = featureDic
                    let indexpath = IndexPath(item: index, section: 0)
                    self?.tableView.reloadRows(at: [indexpath], with: .automatic)
                }
            }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接