CLLocation 管理器两次更新位置

CLLocation manager updating location twice

我的代码中有一个奇怪的问题。我想调用 [locationManager startUpdatingLocation];,当更新完成时 - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 立即停止更新 [locationManager stopUpdatingLocation]。我已将此作为方法中的第一行。但是有时它会被调用两次。谁能给我一些指示,说明为什么会发生这种情况?如果我做的第一件事是在获得第一个更新时停止更新,这对我来说没有意义。部分代码:

-(void)getLocation{

    [locationManager requestWhenInUseAuthorization];
    [locationManager startUpdatingLocation];


}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    [locationManager stopUpdatingLocation]; //kill it NOW or we have duplicates
    NSLog(@"didUpdateToLocation: %@", newLocation);

  //do other stuff....

}

我知道它在重复,因为我偶尔会在屏幕上显示 NSLog 两次。任何帮助将非常感激。谢谢!

通常首先使用缓存数据调用此委托方法,然后使用更新的位置数据再次调用。

您可以在使用前查看位置数据的历史。例如:

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{
   NSTimeInterval t = [[newLocation timestamp] timeIntervalSinceNow];
   // If this location was made more than 3 minutes ago, ignore it.
   if (t < -180) {
      // This is cached data, you don't want it, keep looking
      return;
   }

  [self foundLocation:newLocation];
}

此外,如果您从 CLLocation 管理器请求了高级别的准确性,didUpdateToLocation 委托将在准确性得到改进时被调用多次。如果您真的只想要第一个(可能不是这种情况),请设置一个布尔值来跟踪您已经收到位置的事实,以便您可以忽略后续调用。

要理解回调(locationManager:didUpdateToLocation:fromLocation: or locationManager:didUpdateLocations:)被调用twice(事件超过两次)的原因,我们应该采取查看获取位置数据的 CLLocationManager "behind the screen":

Calculating a phone’s location using just GPS satellite data can take
up to several minutes. iPhone can reduce this time to just **a few seconds**
by using Wi-Fi hotspot and cell tower data to quickly find GPS satellites.

问题 1:谁能告诉我为什么会发生这种情况?

回答:CLLocationManager 尝试尽快为您提供位置,以便您无需等待 几秒 即可处理您的逻辑。为此,它会缓存您上次调用 [locationManager startUpdatingLocation] 时的位置数据。

要验证这一点,您可以尝试卸载您的应用程序,关闭主位置服务,然后重新安装您的应用程序并启动它。 你会看到两件事: (1) 回调 locationManager:didUpdateToLocation:fromLocation: 之前需要几秒钟,并且 (2) 只调用一次 locationManager:didUpdateToLocation:fromLocation:

现在,终止您的应用程序,稍等片刻,然后重新启动它。你会看到两种不同的东西: (1) 几乎立即调用回调(使用缓存数据),并且 (2) 回调被调用两次或更多次(取决于您的等待时间和所需的准确性)

问题 2:所以它进行的第一次更新不是很准确?

答:是的。在使用它之前,您必须检查 "age" 位置(如@Foster Bass)和所需的准确性。

有时,您会看到第一个位置的 "age" 从现在开始已经过去了数百秒。

您可能知道的更多问题here。 希望对你有帮助。