iosnsoperationqueuensinvocationoperation

NSInvocationOperation Cancel usage


Is it right if I cancel an NSInvocationOperation inside the operation? example:

.h file:

//defined in the interface
NSInvocationOperation *op1;
NSOperationQueue  *loadQueue;

.m file:

-(id)init{
    op1 = [NSInvocationOperation new];
    loadQueue = [NSOperationQueue new];
}

-(void)downloadData{
    op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadServerResponse:) object:newerRequest];
    [loadQueue addOperation:op1];
}

Now I have a method to download data from the server. I added a condition to check if there is an error. If so I'm cancelling that operation inside the method and calling back the same method upon retrieving the new login token.

- (void)loadServerResponse{
    if(server_error){
        [op1 cancel];
        //fetch login token again
        [self downloadData];
        return;
    }

Am I doing anything wrong?


Solution

  • First, referencing op1 (which I'm assuming is a class-level ivar) is a Bad Thing™ on multiple levels, the first of which is NSOperationQueue dispatches your operation onto a background thread, so op1 will (at best) be copied into that thread's context and no longer reference the original operation you were attempting to cancel.

    I think you don't need to worry about canceling the operation, given the logic you have shared. You specifically seem to want to call downloadData after canceling, and there's no guarantee that will happen if you cancel the operation first. I would just remove the call to cancel the operation, and continue on. Normally you only cancel a running operation from an external source (say if you receive a notification that your application will enter background state).