使用didUpdateLocations代替didUpdateToLocation

66
随着 iOS6 的发布,苹果希望我们使用 didUpdateLocations 来替代 didUpdateToLocation。有人能解释一下如何正确使用 didUpdateLocations 吗?
6个回答

126

我假设您使用了以下委托来获取最后一个位置?

- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
           fromLocation:(CLLocation *)oldLocation

上述委托在iOS 6中已被弃用。现在应该使用以下内容:

- (void)locationManager:(CLLocationManager *)manager 
     didUpdateLocations:(NSArray *)locations
为了获得最后一个位置,只需获取数组的最后一个对象:
[locations lastObject]

换句话说,[locations lastObject](新的代理)等于newLocation(旧的代理)。


3
@Anne 老地方怎么样? - S.J
@S.J 你可以通过在之前的委托方法调用中保存它来获取旧位置。在这里的答案末尾有一个示例。 - progrmr
2
旧位置对象不会是数组中倒数第二个对象吗? - kraftydevil
这是仍然是CLLocation对象吗?还是一个NSString? - windsound
1
@windsound 是的,[locations lastObject] 是 CLLocation 对象。 - Kamleshwar
但是我们如何从数组中提取坐标,也就是经度和纬度呢? - tryKuldeepTanwar

65

这里没有其他答案解释为什么会有一个位置数组以及如何正确使用提供的新的didUpdateLocations:数组。

废弃locationManager:didUpdateToLocation:fromLocation:并发送位置数组的目的是在后台运行时降低功耗。

从iPhone 5开始,GPS芯片具有存储位置一段时间然后一次性以数组形式传递所有位置的功能。这称为延迟位置更新。这允许主CPU在后台睡眠更长时间。这意味着iOS不必为每个位置更新启动主CPU,而是CPU可以睡眠,而GPS芯片收集位置。

你可以使用deferredLocationUpdatesAvailable方法检查此功能是否可用。如果可用,您可以使用allowDeferredLocationUpdatesUntilTraveled:timeout:方法启用它。某些条件适用,请参见this answer以获取详细信息。

1
这就是我真正想知道的答案。谢谢。 - NightFury

22

它给你一个对象数组,可以访问最后的位置,你可以使用它。

[locations lastObject]

从这个委托方法开始

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations

旧的位置怎么办?如何获取它? - S.J
2
这个 iOS6 调用中不再提供那个(旧位置)。如果需要比较,我通常会将最新的位置存储在一个实例变量 old_location 中。在接收到新位置后,我会将其与实例变量 old_location 进行比较并执行某些操作...或者不执行。然后,我将 old_location 更新为刚刚给我的新位置。这样可以使 old_location 与上次已知位置保持同步。 - Jann

7
这是实现该方法以类似于已弃用方法的方式工作的方法:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    CLLocation *newLocation = locations.lastObject;
    CLLocation *oldLocation;
    if (locations.count > 1) {
        oldLocation = locations[locations.count - 2];
    }
}

3
如果您支持iOS 5和6,则应调用

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations, 

来自较旧的版本

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 

通过构建位置数组来实现函数。


2
值得注意的是,由locationManager:didUpdateLocations:返回的CLLocation对象数组可能包含先前的位置,也可能不包含。换句话说,有时候数组中只包含一个位置。使用以下代码进行检查,如果存在一个以上的对象,我们就可以检索最近的之前的位置:
int objCount = [locations count];
if (objCount > 1) {
    CLLocation *oldLocation = [locations objectAtIndex:objCount - 1];
}

由于数组中至少有一个对象,因此获取当前位置的方法是请求数组中的最后一个对象。即使最后一个对象是唯一的对象,也是可以的:

CLLocation *newLocation = [locations lastObject];

请记住,由于这是一个数组,在上面显示的示例中,oldLocation 不一定是您要查找的位置。这取决于您如何设置 setDistanceFilter: 和 desiredAccuracy: 属性,因为这些属性将影响 locations 数组的填充方式。期望的 oldLocation 可能会深埋在数组中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接