为啥 LocationManager 会多次调用 startUpdatingLocation?

Posted

技术标签:

【中文标题】为啥 LocationManager 会多次调用 startUpdatingLocation?【英文标题】:Why does LocationManager calls startUpdatingLocation multiple times?为什么 LocationManager 会多次调用 startUpdatingLocation? 【发布时间】:2015-11-10 04:16:00 【问题描述】:

为什么位置经理不止一次致电startUpdatingLocation?有时它调用一次,有时它调用它三遍。我不知道为什么;也许你可以帮助我。我有这个来自 GitHub 的代码。

import UIKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate


    let locationManager = CLLocationManager()

    override func viewDidLoad()
    
        super.viewDidLoad()

        self.locationManager.delegate = self
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.startUpdatingLocation()
    

    override func didReceiveMemoryWarning()
    
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) 
        CLGeocoder().reverseGeocodeLocation(manager.location!, completionHandler: (placemarks, error) -> Void in

            if (error != nil)
            
                print("Error: " + error!.localizedDescription)
                return
            

            if placemarks!.count > 0 
                if let pm = placemarks?.first 
                    self.displayLocationInfo(pm)
                
            
            else
            
                print("Error with the data.")
            
        )
    

    func displayLocationInfo(placemark: CLPlacemark)
    

        self.locationManager.stopUpdatingLocation()
        print(placemark.locality)
        print(placemark.postalCode)
        print(placemark.administrativeArea)
        print(placemark.country)
    

    func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
    
        print("Error: " + error.localizedDescription)
    


【问题讨论】:

但是你问为什么 didUpdateLocations 被多次调用,不是吗? 【参考方案1】:

是的,这是标准行为。当您启动定位服务时,您通常会在设备“预热”时收到一系列越来越准确的CLLocation 更新(即horizontalAccuracy 随着时间的推移而减少)。例如,它可能会开始报告它可能已经基于蜂窝塔的位置信息,但随着 GPS 芯片获得更多信息,它可以更好地对您的位置进行三角测量,它会为您提供更新。等等。

如果您想减少这种行为,您可以使用较大的distanceFilter、较小的desiredAccuracy 的组合,或者在获得要进行地理编码的位置后调用stopUpdatingLocation

现在你正在调用stopUpdatingLocation,但你是从reverseGeocodeLocation 的异步调用闭包中调用的。这意味着在调用 reverseGeocodeLocation 的完成处理程序之前,可以进行更多的位置更新。如果您同步调用stopUpdatingLocation(例如在reverseGeocodeLocation 之前),那么您将避免这种行为。

【讨论】:

你有我的示例代码吗?就像您看到的那样,我正在使用 stopUpdatingLocation,但它不像我想要的那样工作。 您在一个方法中停止它,该方法是从 reverseGeocodeLocation 的异步执行闭包中调用的。因此,在调用闭包时,可能已经有更多位置更新。底线,不要异步停止它,而是同步停止它(例如,在您调用 reverseGeocodeLocation 之前)。

以上是关于为啥 LocationManager 会多次调用 startUpdatingLocation?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在循环内调用 publishProgress 并多次调用(没有循环)会显示不同的行为?

为啥 RxJava 的“订阅”方法会被多次调用?

如果我每次都从不同的线程调用事件,为啥会从同一个线程触发事件处理程序的多次执行?

为啥 locationmanager 使用新的 gettime-timestamp 返回旧的位置修复?

为啥 LocationManager 没有 lastKnown 位置?

为啥 ContentObserver 会被多次调用?