Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

[NSOperation cancelAllOperations]; does not stop the operation

xCode 4.4.1 OSX 10.8.2, looks like [operation cancelAllOperations]; isn't working

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    NSOperationQueue *operation = [[NSOperationQueue alloc] init];
    [operation setMaxConcurrentOperationCount: 1];
    [operation addOperationWithBlock: ^{
        for (unsigned i=0; i < 10000000; i++) {
            printf("%i\n",i);
           }
    }];
    sleep(1);
    if ([operation operationCount] > 0) {
        [operation cancelAllOperations];
    }
}

results 9999999

like image 733
Awesome Avatar asked Sep 30 '12 10:09

Awesome


1 Answers

Inside your block, particularly inside the loop, call -isCancelled on the operation. If it's true, then return.

NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
[operationQueue setMaxConcurrentOperationCount: 1];

NSBlockOperation *operation = [[NSBlockOperation alloc] init];
__weak NSBlockOperation *weakOperation = operation;
[operation addExecutionBlock: ^ {
    for (unsigned i=0; i < 10000000; i++) {
        if ([weakOperation isCancelled]) return;
        printf("%i\n",i);
    }
}];
[operationQueue addOperation:operation];

sleep(1);

if ([operationQueue operationCount] > 0) {
    [operationQueue cancelAllOperations];
}

A queue can't just stop the operation's execution arbitrarily - what if some shared resources were being used by the operation that never got cleaned up? It's your responsibility to orderly end the operation when it becomes known to be cancelled. From Apple's docs:

An operation object is responsible for calling isCancelled periodically and stopping itself if the method returns YES.

like image 50
Carl Veazey Avatar answered Jan 05 '23 06:01

Carl Veazey