从父项中删除子视图控制器时,应用程序崩溃

时间:2017-09-28 11:53:55

标签: ios swift3 uiviewcontroller childviewcontroller

我尝试在UIViewControllers之间测试一些动画,在这种特殊情况下,我有一个UIViewController,可以添加另一个UIVC作为其子视图。

所有内容都按预期工作,子视图会被添加并显示,然后在子视图中我有一个UINavigationBar,其左侧栏按钮有一个取消按钮(取消)。

当我点击该按钮时,我会从视图层次结构(从其父视图)触发一个尝试删除此呈现子视图的函数。

父视图中的代码:

    // ViewController -> Parent

lazy var presentButton: UIButton = {
    let b = UIButton(type: .custom)
    b.setTitle("Present", for: .normal)
    b.setTitleColor(.black, for: .normal)
    b.addTarget(self, action: #selector(didTapPresentButton), for: .touchUpInside)
    return b
}()

lazy var childViewController: PresentedViewController = {
    let viewController = PresentedViewController()
    return viewController
}()


@objc func didTapPresentButton() {
    addViewControllerAsChildViewController(childViewController: childViewController)    
}


func addViewControllerAsChildViewController(childViewController: UIViewController) {
    self.addChildViewController(childViewController)
    childViewController.view.frame = CGRect.zero

    self.view.addSubview(childViewController.view)

    let newFrame = view.bounds
    UIView.animate(withDuration: 2) {
        childViewController.view.frame = newFrame
    }
    childViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    childViewController.didMove(toParentViewController: self)
}

如上所示,当我单击当前按钮时,它会实例化子视图并将其设置为动画,到目前为止一直很好。

子视图代码:

// ChildViewController -> Child (ofc)

@objc func didTapCancel() {
    self.willMove(toParentViewController: nil)
    self.view.removeFromSuperview()
    self.removeFromParentViewController()
}

现在在子视图上,当我单击取消按钮时,我知道我必须调用removeFromParentViewController()才能正确删除它,但如果我执行了以下错误,应用程序崩溃:< / p>

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[dismissLayerTest.ChildViewController name]: unrecognized selector sent to instance 0x7fea2f60a920'

然后我尝试对self.removeFromParentViewController()行进行评论,这样一来,应用程序就不会崩溃,但是在父视图控制器上我可以看到视图仍然附加到其父级打印self.childViewControllers.count,它会显示1

你能看出问题所在吗?

由于

1 个答案:

答案 0 :(得分:1)

我找出问题所在。

经过一些测试,我发现在使用lazy时我们不应该使用parent-child View Controllers实例化。

由于我将childViewController实例化为lazy,当我尝试将其从parentViewController中删除时,错误说unrecognized selector sent to instance所以我发现属性指针选择器在parentViewController以某种方式取消分配,因为它失去了参考,因此不知道解雇的是什么孩子。

为了解决这个问题,我删除了lazy实例化,因此它始终保持在范围内,现在我可以成功地从其父范围中删除子项。

var childViewController: ChildViewController = {
    let viewController = ChildViewController()
    return viewController
}()