iphone - 在后台线程上接收 CLLocation 更新

标签 iphone core-location cllocationmanager

我正在尝试使用 iPhone SDK 实现用于位置更新的(非并发)NSOperation。 NSOperation 子类的“核心”是这样的:

- (void)start {
    // background thread set up by the NSOperationQueue
    assert(![NSThread isMainThread]);

    if ([self isCancelled]) {
        return;
    }

    self->locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.desiredAccuracy = self->desiredAccuracy;
    locationManager.distanceFilter = self->filter;
    [locationManager startUpdatingLocation];

    [self willChangeValueForKey:@"isExecuting"];
    self->acquiringLocation = YES;
    [self didChangeValueForKey:@"isExecuting"];
}

- (void)cancel {
    if ( ! self->cancelled ) {
        [self willChangeValueForKey:@"isCancelled"];
        self->cancelled = YES;
        [self didChangeValueForKey:@"isCancelled"];

        [self stopUpdatingLocation];
    }
}

- (BOOL)isExecuting {
    return self->acquiringLocation == YES;
}

- (BOOL)isConcurrent {
    return NO;
}

- (BOOL)isFinished {
    return self->acquiringLocation == NO;
}

- (BOOL)isCancelled {
    return self->cancelled;
}



- (void)stopUpdatingLocation {
    if (self->acquiringLocation) {
        [locationManager stopUpdatingLocation];

        [self willChangeValueForKey:@"isExecuting"];
        [self willChangeValueForKey:@"isFinished"];
        self->acquiringLocation = NO;  
        [self didChangeValueForKey:@"isExecuting"];
        [self didChangeValueForKey:@"isFinished"];
    }
    locationManager.delegate = nil;
}


- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    assert(![NSThread isMainThread]);

    // ... I omitted the rest of the code from this post

    [self stopUpdatingLocation];
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)theError {
    assert(![NSThread isMainThread]);
    // ... I omitted the rest of the code from this post
}

现在,在主线程上,我创建此操作的一个实例并将其添加到 NSOperationQueue 中。 start 方法被调用,但是 -locationManager:... 都没有被调用。委托(delegate)方法被调用。我不明白为什么他们从来没有接到电话。

我确实使界面遵循 <CLLocationManagerDelegate>协议(protocol)。我让 NSOperationQueue 管理此操作的线程,因此它应该全部符合 CLLocationManagerDelegate 文档:

The methods of your delegate object are called from the thread in which you started the corresponding location services. That thread must itself have an active run loop, like the one found in your application’s main thread.

我不知道还可以尝试什么才能使其发挥作用。也许它正盯着我的脸......任何帮助都会受到赞赏。

提前致谢!

最佳答案

您缺少“事件运行循环”部分。在启动方法的末尾添加:

while (![self isCancelled])
  [[NSRunLoop currentRunLoop] runUntilDate:someDate];

关于iphone - 在后台线程上接收 CLLocation 更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4000537/

相关文章:

iphone - UINavigationController 推送转换期间帧速率低

php - APNS沙箱连接失败php文件中出现错误“0”?

ios - 为什么 "Use for Development"没有出现在带有 IOS 8.0 的 Xcode 6 和 iPhone 5 中

ios - 核心位置检测到的最低速度

ios - 位置管理器 didUpdateLocations 未被调用

ios - 当应用程序处于后台并且网络连接丢失时,位置更新计时器不起作用?

ios - 'locationManager(_:didUpdateLocations:)' 的参数具有与协议(protocol) 'CLLocationManagerDelegate' 预期不同的可选性

iphone - iOS Keychain 偶尔会返回空字符串

ios - Swift 按用户与 MKMapItems 的距离组织 UITableView

ios - 无法从 iOS 中的位置管理器获取我的当前地址