在任务之间留出时间 - iOS

Posted

技术标签:

【中文标题】在任务之间留出时间 - iOS【英文标题】:Give a time between tasks - iOS 【发布时间】:2014-04-01 15:46:07 【问题描述】:

我正在通过 iPhone 的 GPS 获取我的位置信息。我想从同一点获取坐标 15 次(以获得最佳水平精度)。

有没有办法等待,例如,一个坐标和另一个坐标之间的 2 秒?

我使用了一个叫做坐标的对象,以经纬度为属性。

.... Exemple code
Coordinate * coord = [[Coordinate alloc] init];
NSMutableArray *coordinates = [[NSMutableArray alloc] init];

for (i=0 ; i<=14; i++)

    coord = newlocation;
    [coordinates addObject:coord];
    .... some code to wait 2 seconds before add a new object to the array....

我尝试使用NSThread sleepfortimeinterval,但视图冻结。

谢谢

【问题讨论】:

【参考方案1】:

而不是像这样使用for 循环,理论上您可以使用每两秒触发一次的重复NSTimer,然后在15 次迭代后使用invalidate 计时器。

但我不建议这样做,而是转向事件驱动模型,等待致电您的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;

【讨论】:

在我的测试中,站在同一个地方,如果我单击两次按钮以获取位置(触摸之间的秒数),horizontal accuracylocation 会因信号振荡而发生变化。如果我只是停止监视位置,该应用将需要很长时间才能再次建立良好的信号。 @FelipeBoszczowski 好的,然后不要关闭定位服务。但我们的想法是持续监控位置,直到(a)您获得所需的准确性;或 (b) 已经过了一定时间。但是不要只是迭代,继续检查位置,因为你可能已经找到了一个好的位置,如果没有,在固定的时间内再次检查是没有意义的,因为在你得到之前检查另一个位置是没有意义的致电您的didUpdateLocations。请参阅我修改后的答案中的代码示例作为建议。根据需要进行更改,但这是事件驱动方法的示例。

以上是关于在任务之间留出时间 - iOS的主要内容,如果未能解决你的问题,请参考以下文章

iOS面试系列-2多线程中同步异步和串行并行之间的逻辑关系(必考,必须掌握)

为任务选择仓库大小

多线程对 IO 密集型任务没有帮助?

无法为任务尝试 ID NNN 释放容器

621. 任务调度器

睡眠的资源利用