locationManager:didUpdateLocations:总是被调用几次

当视图确实出现时,我开始更新当前位置,并且在调用locationManager:didUpdateLocations:时停止更新位置。 但为什么locationManager:didUpdateLocations:总是被多次调用? 我错过了什么?

 #import "ViewController.h" @interface ViewController (){ CLLocationManager *locationManager; // location manager for current location } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self startUpdatingCurrentLocation]; } - (void)startUpdatingCurrentLocation { if (!locationManager) { locationManager = [[CLLocationManager alloc] init]; [locationManager setDelegate:self]; locationManager.distanceFilter = 10.0f; // we don't need to be any more accurate than 10m } [locationManager startUpdatingLocation]; } -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ [locationManager stopUpdatingLocation]; } @end 

可能取决于您设置到locationManager的准确性。 您有三种本地化的Cell Radio,WiFi Map,GPS。 如果您将精度设置得最好,位置pipe理器将继续检查您的位置,如果精度更高的位置超出距离filter的范围,委托方法将再次被调用。

SWIFT版本

我做了一个助手类HelperLocationManager并添加了notification- observer模式

 import UIKit import CoreLocation class HelperLocationManager: NSObject { var locationManager = CLLocationManager() static let sharedInstance = HelperLocationManager() var currentLocation :CLLocation? var notGotUserLocation = true override init() { super.init() var code = CLLocationManager.authorizationStatus() if code == CLAuthorizationStatus.NotDetermined { locationManager.requestAlwaysAuthorization() locationManager.requestWhenInUseAuthorization() } locationManager.requestAlwaysAuthorization() locationManager.requestWhenInUseAuthorization() locationManager.delegate = self locationManager.distanceFilter = 100; } } extension HelperLocationManager: CLLocationManagerDelegate{ func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) { var locValue = locations.last as! CLLocation println(locValue) self.currentLocation = locValue NSNotificationCenter.defaultCenter().postNotificationName("sendCurrentAddressToViewController", object:self.currentLocation) notGotUserLocation = false } func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) { println("Your error is ", error.localizedDescription) } } 

现在,如果你的Viewcontroller类需要的位置,然后把一个观察员在那里

 var helperLocation:HelperLocationManager? 

viewDidLoad

  override func viewDidLoad() { helperLocation = HelperLocationManager() NSNotificationCenter.defaultCenter().addObserver(self, selector: "getCurrentAddressToViewController:", name: "sendCurrentAddressToViewController", object: nil) } 

//和观察者一样

  func getCurrentAddressToViewController(notification: NSNotification) { currentLocation = notification.object as? CLLocation NSNotificationCenter.defaultCenter().removeObserver(self, name: "sendCurrentAddressToViewController", object: nil) } 

//虽然didUpdateLocation被多次调用,但是只有在获取位置后才能移除observer ,所以您只能获得一次位置。

编辑:我refractored这个助手类,所以你不需要添加notificationobserver模式

 class HelperLocationManager: NSObject { private lazy var locationManager = CLLocationManager() static let sharedInstance = HelperLocationManager() var currentLocation :CLLocation? override init() { super.init() locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.delegate = self } } extension HelperLocationManager: CLLocationManagerDelegate{ func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) { switch status { case CLAuthorizationStatus.NotDetermined: locationManager.requestWhenInUseAuthorization() case CLAuthorizationStatus.Restricted: PrinterHelper.messagePrinter("Restricted Access to location") case CLAuthorizationStatus.Denied: PrinterHelper.messagePrinter("User denied access to location") case CLAuthorizationStatus.AuthorizedWhenInUse: if #available(iOS 9.0, *) { locationManager.requestLocation() } else { locationManager.startUpdatingLocation() } default: PrinterHelper.messagePrinter("default authorization") } } func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let locValue = locations.last HelperLocationManager.sharedInstance.currentLocation = locValue locationManager.stopUpdatingLocation() } func locationManager(manager: CLLocationManager, didFailWithError error: NSError) { PrinterHelper.errorPrinter(error.localizedDescription) } } 

查看控制器你需要获得用户权限

 var helperLocationManager:HelperLocationManager? 

viewDidLoad

  override func viewDidLoad() { helperLocationManager = HelperLocationManager.sharedInstance } 

并获得你需要调用单身属性currentLocation as的位置

  if let userCurentLoc = HelperLocationManager.sharedInstance.currentLocation{ //userCurrentLoc is the user Location } 

为了补充Anish的回答,如果你想知道你的助手类何时没有调用位置更新(即,当你closures了你的位置服务),你可以使用locationManager:didChangeAuthorizationStatus:方法来pipe理它,如果你的位置是不允许,你可以打电话给另一个notification- observer

 func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) { var shouldIAllow = false switch status { case CLAuthorizationStatus.Restricted: locationStatus = "Restricted Access to location" case CLAuthorizationStatus.Denied: locationStatus = "User denied access to location" case CLAuthorizationStatus.NotDetermined: locationStatus = "Status not determined" default: locationStatus = "Allowed to location Access" shouldIAllow = true } if (shouldIAllow == true) { print("Location to Allowed") // Start location services locationManager!.startUpdatingLocation() } else { print("Denied access: \(locationStatus)") NSNotificationCenter.defaultCenter().postNotificationName("deniedLocation", object:locationStatus) } }