不是有for
循环这样,理论上可以使用重复NSTimer
即每两秒钟发射,然后invalidate
计时器后15次迭代。
但我不会建议这样做,而是转而采用事件驱动模式,等待拨打didUpdateLocations
。如果didUpdateLocations
尚未更新,则在两秒内检查没有意义。同样,在30秒内重复检查15次也没有意义,例如,5秒后您是否获得了非常准确的位置。
我建议开始监控的位置,观看的位置,因为他们进来,随后调用didUpdateLocations
,并检查CLLocation
的horizontalAccuracy
(它告诉你位置的精确程度)。一旦你到达期望的horizontalAccuracy
,你可以声明成功(例如停止监控位置或其他)。如果您愿意,也可以建立一个NSTimer
,在30秒后自动关闭位置监控。
例如:
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"%s", __PRETTY_FUNCTION__);
[self startStandardUpdates];
// after 30 seconds, if we haven't found a location, declare success with whatever we got (if anything)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(30.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self stopStandardUpdates]; // stop monitoring location if you want
if (!self.foundLocation) {
if (self.bestLocation) {
NSLog(@"Didn't find perfect location, but location has accuracy of %.1f meters", self.bestLocation.horizontalAccuracy);
} else {
NSLog(@"Even after 30 seconds, did not find any locations!");
}
}
});
}
#pragma mark - Location Services
- (void)startStandardUpdates
{
// Create the location manager if this object does not
// already have one.
if (nil == self.locationManager)
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// Set a movement threshold for new events.
self.locationManager.distanceFilter = 5;
[self.locationManager startUpdatingLocation];
}
- (void)stopStandardUpdates
{
[self.locationManager stopUpdatingLocation];
self.locationManager = nil;
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation* location = [locations lastObject];
NSLog(@"%s: horizontalAccuracy = %.1f", __FUNCTION__, location.horizontalAccuracy);
if (location.horizontalAccuracy < 0) // not a valid location
return;
// this checks to see if the location is more accurate than the last;
// or you might just want to eliminate this `if` clause, because if
// you get updated location, you can probably assume it's better than
// the last one (esp if the user might be moving)
if (!self.bestLocation || location.horizontalAccuracy <= self.bestLocation.horizontalAccuracy) {
self.bestLocation = location;
}
if (location.horizontalAccuracy <= 5) { // use whatever you want here
NSLog(@"Found location %@", location);
self.foundLocation = YES;
[self stopStandardUpdates]; // stop it if you want
}
}
它使用以下属性:
@property (nonatomic, strong) CLLocationManager *locationManager;
@property (nonatomic, strong) CLLocation *bestLocation;
@property (nonatomic) BOOL foundLocation;
来源
2014-04-01 16:02:46
Rob
在我的测试中,站在同一个地方,如果我两次单击按钮来获得位置(secods在触摸之间),“水平精度”和“位置”由于信号振荡而改变。如果我只是停止监控位置,应用程序将需要很长时间才能再次建立良好的信号。 –
@FelipeBoszczowski好的话,不要关闭位置服务。但是,这个想法是保持监测地点,直到(a)你获得所需的准确性;或(b)已经过了一段时间。但是,不要只是迭代,保持检查位置,因为你可能已经找到了一个好的位置,如果没有,在固定的时间内再次检查没有意义,因为在你获得之前没有必要检查另一个位置打电话给你的'didUpdateLocations'。请参阅我的修订答案中的代码示例作为建议。按照您认为合适的方式进行更改,但这是事件驱动方法的示例。 – Rob