Ios 当函数执行时,单击导航控制器上的后退按钮时,应用程序崩溃

Ios 当函数执行时,单击导航控制器上的后退按钮时,应用程序崩溃,ios,swift,uiviewcontroller,uinavigationcontroller,Ios,Swift,Uiviewcontroller,Uinavigationcontroller,在慢速连接上,当我点击VC上的后退按钮时,它会在访问导航控制器时崩溃。VC已解除分配,但在返回到另一个视图后执行setNavBarTitle。我知道函数正在执行,而VC已经被解除分配,但我不知道什么是最好的方式来处理这种情况 override func viewWillAppear(_ animated: Bool){ super.viewWillAppear(animated) fetchProfile(clientId: clientId) { (result, error

在慢速连接上,当我点击VC上的后退按钮时,它会在访问导航控制器时崩溃。VC已解除分配,但在返回到另一个视图后执行setNavBarTitle。我知道函数正在执行,而VC已经被解除分配,但我不知道什么是最好的方式来处理这种情况

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

    fetchProfile(clientId: clientId) { (result, error) in
        if result?.data != nil { 
                if (result?.success)! {
                    self.clientProfile = result!.data!
                    // Avatar
                    let clientImageView = UIImageView()

                    if let url = URL(string: result!.data!.pic_url!) {
                        clientImageView.image = UIImage(named: "System/defaultAvatar")
                        let task = URLSession.shared.dataTask(with: url) { data, response, error in
                            guard let data = data, error == nil else { return }

                            // WARNING: UIImageView.image must be used from main thread only                                
                            clientImageView.image = UIImage(data: data)
                            self.setNavBarTitle(image: clientImageView.image!)
                        }
                        task.resume()
                    } 
                }
            } 
        }
    }
}

private func setNavBarTitle(image: UIImage) {
    // Crashes here -> Thread 11: Fatal error: Unexpectedly found nil while unwrapping an Optional value
    let navigationBarHeight: CGFloat = self.navigationController!.navigationBar.frame.height
}

您可以尝试在方法回调中使用
[weak self]
,这样即使在VC解除分配后调用该方法,也不会导致崩溃,因为self不存在:

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

    fetchProfile(clientId: clientId) { [weak self] (result, error) in
        if result?.data != nil { 
                if (result?.success)! {
                    self?.clientProfile = result!.data!
                    // Avatar
                    let clientImageView = UIImageView()

                    if let url = URL(string: result!.data!.pic_url!) {
                        clientImageView.image = UIImage(named: "System/defaultAvatar")
                        let task = URLSession.shared.dataTask(with: url) { data, response, error in
                            guard let data = data, error == nil else { return }

                            DispatchQueue.main.async {
                                clientImageView.image = UIImage(data: data)
                                self?.setNavBarTitle(image: clientImageView.image!)
                            } 


                        }
                        task.resume()
                    } 
                }
            } 
        }
    }
}

private func setNavBarTitle(image: UIImage) {
    // Crashes here -> Thread 11: Fatal error: Unexpectedly found nil while unwrapping an Optional value
    guard let navigationBarHeight: CGFloat = self.navigationController?.navigationBar.frame.height else {
        return
    }
}

永远不要从后台线程执行UI更改。“警告:UIImageView.image必须仅从主线程使用”将显示为self?.setNavBarTitle(image:clientImageView.image!)行,该行是否也需要进入DispatchQueue内?是的,对不起,我也会把它放在我的答案里。你能试试它是不是因为self弱而崩溃吗?Tx。到目前为止还没有崩溃。不过我会继续测试它。我还在我的答案中添加了setNavBarTitle函数,在您的代码中,您使用self.navigationController!-如果VC没有navigationController,那么末尾的感叹号也可能导致应用程序崩溃。我用“?”更新了它,在我的回答中,这更安全。是的,我更新了,它仍然崩溃。我在它周围加了一个防护装置,防止它撞坏。大多数情况下,它会打印“navigationBarHeight nil returning”。这是守卫的解决方案还是我们遗漏了什么?guard let navigationBarHeight=self.navigationController?.navigationBar.frame.height else{print(“navigationBarHeight nil returning”)return}