Add and remove observer for KVO "myLocation" in GMSMapView

I have looked through every possible solution but could not find the exact one. My problem: I am using a navigation controller and a view manager with a GMSMapView. When I change to another view from the GMSMapView, the application crashes, discarding that "the 0x7f9b79c53c20 instance of the GMSMapView has been freed and the key-value observers were still registered with it."

But if I try to remove the observer in viewwilldisappear or deinit, the application crashes again with the exception "Unable to remove observer for key path" myLocation "because it is not registered as an observer.

Can anyone please help with a better solution. Here is my code:

override func viewDidLoad() {

open.target = self.revealViewController()
open.action = "revealToggle:"
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())

locationManager.delegate = self
mapView.delegate = self

if (locationManager.respondsToSelector(Selector("requestWhenInUseAuthorization"))) {
locationManager.requestWhenInUseAuthorization()
}
 mapView.myLocationEnabled = true

placesClient = GMSPlacesClient()  
}

override func viewWillAppear(animated: Bool) {

    mapView.addObserver(self, forKeyPath: "myLocation", options: NSKeyValueObservingOptions.New, context: nil)

}

deinit{
removeObserver(self, forKeyPath: "myLocation", context: nil)

}
 override func viewWillDisappear(animated: Bool) {


   // removeObserver(self, forKeyPath: "myLocation")
}

 override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
    if !didFindMyLocation {
        let myLocation: CLLocation = change[NSKeyValueChangeNewKey] as CLLocation
        mapView.camera = GMSCameraPosition.cameraWithTarget(myLocation.coordinate, zoom: 15.0)
        mapView.settings.myLocationButton = true
        didFindMyLocation = true
    }
}

      

+3


source to share


2 answers


I figured out this problem. Actually the problem was that I used removeObserver (self, forKeyPath: "myLocation", context: nil) instead of mapView.removeObserver (self, forKeyPath: "myLocation", context: nil)



0


source


A KVO based on a new closure for Swift 3.2+ looks like this:

class myClass {
    private var observation: NSKeyValueObservation?

    func startObserving() {
       self.observation = self.mapView.observe(\.myLocation, options: [.new, .old], changeHandler: { _, change in
                guard let newLocation = change.newValue else { return }
                //Do something with newlocation
            })
    }
}

      

startObserving()

function startObserving()

anywhere.



Canceling the observer is optional, you can just let it go outside the box. If you want to invalidate it, just do:

self.observation?.invalidate()

      

0


source







All Articles