user2722667
user2722667

Reputation: 8651

Swift MKMapView sometimes becomes nil and app crashes

I am displaying a map like this:

//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
    }

If I exit out from the VC and go back again a few times fast the app will eventually crash because MKMapView becomes nil.

The crash happens here self.mapView.addAnnotation(annotation)

I am not sure why but my guess is that geocoder.geocodeAddressString has not finished loading/searching and if I exit out from the VC fast enough mapView becomes nil

Upvotes: 3

Views: 1035

Answers (1)

rmaddy
rmaddy

Reputation: 318774

You set self.mapView to nil in your viewWillDisappear method. So your app will crash anytime you leave the view controller before the geocoder is done.

Simply add a proper check for nil in the geocoder block.

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)
                    }
                }
            }
        }
    }
}

Upvotes: 3

Related Questions