Ios 尝试取消加载视图时应用程序崩溃

Ios 尝试取消加载视图时应用程序崩溃,ios,swift,Ios,Swift,我正在开发一个天气应用程序,每当用户的位置更新时,我都会打一个网络电话,而这正是应用程序每次启动的时候 为了更好的用户体验,我还提供了一个加载视图,但是大约十分之一的应用程序启动时,它会在试图从superview中删除加载视图的背景视图时崩溃,我不知道为什么 编辑:我已经尝试使containerView成为可选的,它解决了崩溃问题,但是加载视图永远保持不变,因为在这些情况下containerView不会被取消 如果有人想帮我,我会将代码附加到下面的数据加载类和调用站点 提前感谢您抽出时间 cla

我正在开发一个天气应用程序,每当用户的位置更新时,我都会打一个网络电话,而这正是应用程序每次启动的时候

为了更好的用户体验,我还提供了一个加载视图,但是大约十分之一的应用程序启动时,它会在试图从superview中删除加载视图的背景视图时崩溃,我不知道为什么

编辑:我已经尝试使containerView成为可选的,它解决了崩溃问题,但是加载视图永远保持不变,因为在这些情况下containerView不会被取消

如果有人想帮我,我会将代码附加到下面的数据加载类和调用站点

提前感谢您抽出时间

class WEDataLoadingVC: UIViewController {

var containerView: UIView!

override func viewDidLoad() {
    super.viewDidLoad()
    
}


func presentLoadingView() {
    containerView = UIView(frame: self.view.bounds)
    view.addSubview(containerView)
    containerView.backgroundColor = .systemBackground
    containerView.alpha = 0
    UIView.animate(withDuration: 0.3) { self.containerView.alpha = 0.8 }
    let activityIndicator = UIActivityIndicatorView(style: .large)
    containerView.addSubview(activityIndicator)
    activityIndicator.centerX(in: containerView, constant: 0)
    activityIndicator.centerY(in: containerView, constant: 0)
    activityIndicator.startAnimating()
}

func dismissLoadingView() {
    DispatchQueue.main.async {
        self.containerView.removeFromSuperview()
        self.containerView = nil
    }
}
以及呼叫站点

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let location = locations.last else { return /* present alert */}
    let lat = String(location.coordinate.latitude)
    let lon = String(location.coordinate.longitude)
    LocationManager.shared.getLocationName(for: location) { placemark in
        guard let place = placemark?.locality else {
            /* present alert*/
            return
        }
        DispatchQueue.main.async { self.locationView.update(with: place) }
    }
    presentLoadingView()
    NetworkManager.shared.getWeatherDataFor(lat: lat, lon: lon) { [weak self] result in
        guard let self = self else { return }
        self.dismissLoadingView()
        switch result {
        case .success(let data):
            DispatchQueue.main.async {
                self.currentConditionsView.update(with: data)
                self.lookAheadView.update(with: data)
                self.todayView.update(with: data)
            }
        case .failure(let error):
            /* present alert */
            print(error.rawValue)
        }
    }
}

您可以尝试执行以下操作:

var activityIndicator: UIActivityIndicatorView

func presentLoadingView() {
    if containerView == nil {
        containerView = UIView(frame: self.view.bounds)
        view.addSubview(containerView)
        containerView.backgroundColor = .systemBackground
        containerView.alpha = 0
        UIView.animate(withDuration: 0.3) { self.containerView.alpha = 0.8 }
        activityIndicator = UIActivityIndicatorView(style: .large)
        containerView.addSubview(activityIndicator)
        activityIndicator.centerX(in: containerView, constant: 0)
        activityIndicator.centerY(in: containerView, constant: 0)
    }
    else { 
        self.containerView.isHidden = false
        activityIndicator.startAnimating()
    }
}

func dismissLoadingView() {
    DispatchQueue.main.async {
        self.activityIndicator.stopAnimating()
        self.containerView.isHidden = true
   }
}

错误消息?堆栈跟踪?如果您同时提到错误消息,以及它在哪一行崩溃,则会更容易发现问题是否确实只调用了一次didUpdateLocations?因为它应该在每次位置改变时调用,这会导致代码中出现很多争用问题,
dismissLoadingView
是否可以连续调用两次?如果是,您应该检查
containerView
是否为零。事实上,由于将其设置为nil,您可能应该将其声明为
UIView?
,并在使用时编写测试。错误出现在dismissLoadingView()函数中从superview中删除containerView的行上。我也尝试过使containerView成为可选的,但是在以前它会崩溃的情况下,现在加载视图不再从superview中删除。除了提供的代码中的调用之外,没有任何其他调用此函数。