Ios 添加和删除KVO的观察者“;“我的位置”;在GMSMapView中

Ios 添加和删除KVO的观察者“;“我的位置”;在GMSMapView中,ios,swift,xcode6,key-value-observing,gmsmapview,Ios,Swift,Xcode6,Key Value Observing,Gmsmapview,我找遍了所有可能的解决办法,但找不到确切的办法。我的问题是:我正在使用带有GMSMapView的导航控制器和viewcontroller。当我从GMSMapView导航到其他视图时,该应用程序崩溃,出现一个例外,即“GMSMapView类的实例0x7f9b79c53c20被释放,而键值观察器仍在注册。” 但如果我试图删除ViewWillEnglish或Denit中的观察者,应用程序将再次崩溃,出现一个异常“无法从中删除关键路径“myLocation”的观察者,因为它未注册为观察者 谁能帮我找到最

我找遍了所有可能的解决办法,但找不到确切的办法。我的问题是:我正在使用带有GMSMapView的导航控制器和viewcontroller。当我从GMSMapView导航到其他视图时,该应用程序崩溃,出现一个例外,即“GMSMapView类的实例0x7f9b79c53c20被释放,而键值观察器仍在注册。”

但如果我试图删除ViewWillEnglish或Denit中的观察者,应用程序将再次崩溃,出现一个异常“无法从中删除关键路径“myLocation”的观察者,因为它未注册为观察者

谁能帮我找到最好的解决方案。这是我的密码:

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
    }
}
override func viewDidLoad(){
open.target=self.revealViewController()
open.action=“Revealtogle:”
self.view.addgestureRecognitizer(self.revealViewController().pangestureRecognitizer())
locationManager.delegate=self
mapView.delegate=self
if(locationManager.respondsToSelector(选择器(“RequestWhenUseAuthorization”)){
locationManager.RequestWhenUseAuthorization()
}
mapView.myLocationEnabled=true
placesClient=GMSPlacesClient()
}
覆盖功能视图将出现(动画:Bool){
addObserver(self,forKeyPath:“myLocation”,选项:NSKeyValueObservingOptions.New,上下文:nil)
}
脱硝{
removeObserver(self,forKeyPath:“myLocation”,上下文:nil)
}
覆盖功能视图将消失(动画:Bool){
//removeObserver(自我,分叉路径:“myLocation”)
}
重写func observeValueForKeyPath(键路径:字符串,对象对象:AnyObject,更改:[NSObject:AnyObject],上下文:UnsafeMutablePointer){
如果!发现了错配{
让myLocation:CLLocation=将[NSKeyValueChangeNewKey]更改为CLLocation
mapView.camera=GMSCameraPosition.cameraWithTarget(myLocation.coordinate,zoom:15.0)
mapView.settings.myLocationButton=true
didFindMyLocation=true
}
}

我已经解决了这个问题。实际上,我担心的是我使用了removeObserver(self,forKeyPath:“myLocation”,context:nil)而不是mapView。removeObserver(self,forKeyPath:“myLocation”,context:nil)

用于Swift 3.2+的新的基于闭包的KVO如下所示:

class myCustomView: UIView {
    let camera = GMSCameraPosition(target: CLLocationCoordinate2D(latitude: 52.5067614, longitude: 13.2846524), zoom: 10, bearing: 0, viewingAngle: 0)
    lazy var mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
    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()
函数

使观察者无效不是强制性的,您可以让它超出范围。如果确实要使其无效,请执行以下操作:

self.observation?.invalidate()

如果在VIEWWILLEXPEND:中注册,请使用VIEWWILLEXPENCE删除观察者。如果在viewDidLoad中注册,请使用deinit取消注册观察者。请始终使用计数器部分进行注册和注销,这应该没问题。@GeneratorOfOne:谢谢您宝贵的时间。我已经解决了这个问题。实际上,我担心的是我使用了removeObserver(self,forKeyPath:“myLocation”,上下文:nil)而不是mapView。removeObserver(self,forKeyPath:“myLocation”,上下文:nil)谢谢@Sandeep@AmritSidhu:你在评论中的回答对我帮助很大。您应该将您的解决方案添加为答案,而不是注释,以便您可以轻松找到解决方案。