【发布时间】:2012-09-18 02:56:09
【问题描述】:
随着 iOS6 的发布,Apple 希望我们使用 didUpdateLocations 而不是 didUpdateToLocation。谁能解释一下如何正确使用 didUpdateLocations?
【问题讨论】:
标签: ios objective-c swift core-location cllocationmanager
随着 iOS6 的发布,Apple 希望我们使用 didUpdateLocations 而不是 didUpdateToLocation。谁能解释一下如何正确使用 didUpdateLocations?
【问题讨论】:
标签: ios objective-c swift core-location cllocationmanager
我假设您使用以下委托来获得最后一个位置?
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
上面的委托在 iOS 6 中已被弃用。现在应该使用以下代理:
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
为了获取最后的位置,只需获取数组的最后一个对象:
[locations lastObject]
换句话说,[locations lastObject](新委托)等于newLocation(旧委托)。
【讨论】:
这里没有其他答案解释为什么有一个位置数组以及如何正确使用提供的新的 didUpdateLocations: 数组。
弃用locationManager:didUpdateToLocation:fromLocation: 并改为发送位置的NSArray 的目的是降低在后台运行时的功耗。
从 iPhone 5 开始,GPS 芯片能够将位置存储一段时间,然后以阵列的形式一次性提供所有位置。这称为延迟位置更新。这允许主 CPU 在后台休眠更长的时间。这意味着 iOS 不必每次更新位置都启动主 CPU,CPU 可以休眠,而 GPS 芯片会收集位置。
您可以使用deferredLocationUpdatesAvailable 方法检查此功能。如果可用,您可以使用 allowDeferredLocationUpdatesUntilTraveled:timeout: 方法启用它。某些条件适用,有关详细信息,请参阅this answer。
【讨论】:
它为您提供对象数组来访问您可以使用的最后一个位置
[locations lastObject]
来自这个委托方法
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
【讨论】:
old_location 的实例变量中。到达新位置后,我与实例变量old_location 进行比较,然后做某事……或不做。然后我将old_location 更新为刚刚给我的新的。这使old_location 与最后一个已知位置保持同步。
这就是如何实现该方法以与已弃用的方法类似的方式
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *newLocation = locations.lastObject;
CLLocation *oldLocation;
if (locations.count > 1) {
oldLocation = locations[locations.count - 2];
}
}
【讨论】:
如果你同时支持 iOS 5 和 6,你应该调用
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations,
来自老
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
函数,通过构建一个位置数组。
【讨论】:
值得注意的是,locationManager:didUpdateLocations: 返回的 CLLocation 对象数组可能包含也可能不包含以前的位置。换句话说,在极少数情况下,阵列中可能只有一个位置。使用以下检查,如果有多个对象,我们可以检索最近的先前位置:
int objCount = [locations count];
if (objCount > 1) {
CLLocation *oldLocation = [locations objectAtIndex:objCount - 1];
}
由于数组中至少有一个对象,因此通过请求数组中的最后一个对象来检索当前位置。即使最后一个对象是唯一的对象,也没关系:
CLLocation *newLocation = [locations lastObject];
请记住,因为这是一个数组,所以上面示例中的 oldLocation 不一定是您要查找的那个。这取决于您如何设置DistanceFilter: 和 desiredAccuracy: 属性,因为这些属性将影响您的位置数组的填充方式。所需的 oldLocation 可能会在数组中埋得更深。
【讨论】: