layoutIfNeeded()上的模糊崩溃

时间:2017-02-07 10:05:48

标签: ios swift debugging uinavigationcontroller

出现崩溃:

navigationController.view.layoutIfNeeded()
  

日志:致命错误:在解包可选值时意外发现nil

首次启动应用程序时出现崩溃(xcode构建之后),当我的用户断开连接并重新连接其帐户时。如果我用已经连接的用户重新启动应用程序就可以了。

完整功能代码:

func prepareControllers(){
    homeTabs = [homeView, teamView, rankView, generalView]

    for view in homeTabs{
        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(ABMainViewController.didTapTab(_:))))
    }

    mainControllers = [
        UIStoryboard(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "home") as! ABHomeViewController,
        UIStoryboard(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "teamController") as! ABTeamViewController,
        UIStoryboard(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "leaderboardController") as! ABLeaderboardViewController,
        ABInformationViewController(nibName: "ABInformationViewController", bundle: Bundle.main) 
    ]

    var previousController: UINavigationController? = nil

    for viewController in mainControllers{
        viewController.delegate = self;
        let navigationController = UINavigationController(rootViewController: viewController)
        navigationControllers.append(navigationController)
        navigationController.view.frame = scrollView.bounds
        navigationController.setNavigationBarHidden(true, animated: false)
        navigationController.view.translatesAutoresizingMaskIntoConstraints = false

        scrollView.addSubview(navigationController.view)

        scrollView.addConstraint(NSLayoutConstraint(item: navigationController.view, attribute: .top, relatedBy: .equal, toItem: scrollView, attribute: .top, multiplier: 1, constant: 0))
        scrollView.addConstraint(NSLayoutConstraint(item: navigationController.view, attribute: .height, relatedBy: .equal, toItem: scrollView, attribute: .height, multiplier: 1, constant: 0))
        scrollView.addConstraint(NSLayoutConstraint(item: navigationController.view, attribute: .width, relatedBy: .equal, toItem: scrollView, attribute: .width, multiplier: 1, constant: 0))

        if(previousController != nil){
            scrollView.addConstraint(NSLayoutConstraint(item: navigationController.view, attribute: .left, relatedBy: .equal, toItem: previousController!.view, attribute: .right, multiplier: 1, constant: 0))
        }else{
            scrollView.addConstraint(NSLayoutConstraint(item: navigationController.view, attribute: .leading, relatedBy: .equal, toItem: scrollView, attribute: .leading, multiplier: 1, constant: 0))
        }

        navigationController.view.layoutIfNeeded()  // CRASH HERE
        previousController = navigationController
    }

    scrollView.addConstraint(NSLayoutConstraint(item: scrollView, attribute: .trailing, relatedBy: .equal, toItem: previousController!.view, attribute: .trailing, multiplier: 1, constant: 0))
}

在调试导航器中:

    0x102b691f8 <+116>: bl     0x102a5cb80               ; function signature    specialization <preserving fragile attribute, Arg[1] = [Closure Propagated : reabstraction thunk helper from @callee_owned (@unowned Swift.UnsafeBufferPointer<Swift.UInt8>) -> () to @callee_owned (@unowned Swift.UnsafeBufferPointer<Swift.UInt8>) -> (@out ()), Argument Types : [@callee_owned (@unowned Swift.UnsafeBufferPointer<Swift.UInt8>) -> ()]> of generic specialization <preserving fragile attribute, ()> of Swift.StaticString.withUTF8Buffer <A> ((Swift.UnsafeBufferPointer<Swift.UInt8>) -> A) -> A
 ->  0x102b691fc <+120>: brk    #0x1    //HERE

有没有办法找到这个展开价值在哪里? 如果有人有想法,我该如何解决它或如何更清楚地调试它。谢谢你!

2 个答案:

答案 0 :(得分:0)

日志说明navigationController.view.layoutIfNeeded()中的某个实例为零。表示navigationControllerview为零。

在调用方法viewDidLoad之前,控制器的所有视图都是nil。或者,在您的代码中,您实例化UINavigationController并在此之后直接调用它的主视图。

如果你真的想调用layoutIfNeeded方法,子类UINavigationController并在viewDidLoadviewWillAppearviewDidAppear中调用方法,即使我认为你如果您的约束得到很好的实施,则不必调用它

class CustomNavigationController: UINavigationController {
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        self.view.layoutIfNeeded()
    }
}

答案 1 :(得分:0)

正如EPerrin95所说,也许你正在尝试布局尚不存在的东西。应在viewDidAppear或至少viewWillAppear。

之后调用布局方法