Receiving CLLocation updates on a background thread

烈酒焚心 提交于 2019-12-09 01:05:52

问题


I am trying to implement a (non-concurrent) NSOperation for location updates using the iPhone SDK. The "meat" of the NSOperation subclass goes something like this:

- (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
}

Now, on the main thread I create an instance of this operation and add it to an NSOperationQueue. The start method gets called, however none of the -locationManager:... delegate methods get called. I don't get it why they never get called.

I did make the interface adhere to the <CLLocationManagerDelegate> protocol. I'm letting the NSOperationQueue manage the thread for this operation, so it should all be conforming to the CLLocationManagerDelegate documentation:

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.

I am not sure what else to try for this to work. Maybe it's staring me in the face... Any help is appreciated.

Thanks in advance!


回答1:


You are missing the "active run loop" part. At the end of your start method add:

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


来源:https://stackoverflow.com/questions/4000537/receiving-cllocation-updates-on-a-background-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!