Swift MKMapView 有时变为 nil 并且应用程序崩溃

Swift MKMapView sometimes becomes nil and app crashes

我正在显示这样的地图:

//Map
    @IBOutlet var mapView: MKMapView!

    var location: String?

    override func viewDidLoad() {
        super.viewDidLoad()

        self.mapView.delegate = self

        if let location = location {
            let address = location
            let geocoder = CLGeocoder()
            geocoder.geocodeAddressString(address) { (placemarks, error) in
                if let placemarks = placemarks {
                    if placemarks.count != 0 {
                        let annotation = MKPlacemark(placemark: placemarks.first!)
                        self.mapView.addAnnotation(annotation)
                        let span = MKCoordinateSpanMake(0.1, 0.1)
                        let region = MKCoordinateRegionMake(annotation.coordinate, span)
                        self.mapView.setRegion(region, animated: false)
                    }
                }
            }
        }
    }

    //Fixing map memory issue
    override func viewWillDisappear(_ animated:Bool){
        super.viewWillDisappear(animated)
        self.applyMapViewMemoryFix()
    }

    //Fixing map memory issue
    func applyMapViewMemoryFix(){
        switch (self.mapView.mapType) {
        case MKMapType.hybrid:
            self.mapView.mapType = MKMapType.standard
            break;
        case MKMapType.standard:
            self.mapView.mapType = MKMapType.hybrid
            break;
        default:
            break;
        }
        self.mapView.showsUserLocation = false
        self.mapView.delegate = nil
        self.mapView.removeFromSuperview()
        self.mapView = nil
    }

如果我退出 VC 并再次快速返回几次,应用程序最终会崩溃,因为 MKMapView 变为 nil。

崩溃发生在这里self.mapView.addAnnotation(注释)

我不确定为什么,但我的猜测是 geocoder.geocodeAddressString 还没有完成 loading/searching 如果我足够快地退出 VC mapView 就变成零

您在 viewWillDisappear 方法中将 self.mapView 设置为 nil。因此,只要您在地理编码器完成之前离开视图控制器,您的应用就会崩溃。

只需在地理编码器块中为 nil 添加适当的检查。

override func viewDidLoad() {
    super.viewDidLoad()

    self.mapView.delegate = self

    if let location = location {
        let address = location
        let geocoder = CLGeocoder()
        geocoder.geocodeAddressString(address) { (placemarks, error) in
            if let placemarks = placemarks {
                if placemarks.count != 0 {
                    if let mapView = self.mapView {
                        let annotation = MKPlacemark(placemark: placemarks.first!)
                        mapView.addAnnotation(annotation)
                        let span = MKCoordinateSpanMake(0.1, 0.1)
                        let region = MKCoordinateRegionMake(annotation.coordinate, span)
                        mapView.setRegion(region, animated: false)
                    }
                }
            }
        }
    }
}