1

I make a queue

NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];

I send the queue to my async request

[NSURLConnection sendAsynchronousRequest:req queue:operationQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    dispatch_async(dispatch_get_main_queue(), ^{
        // ... do stuff here
    });
}];

I cancel my operations prematurely

[operationQueue cancelAllOperations];

However, I can see my async's "completion" code still running. How come this scenario doesn't work like I expected?

Dan F
  • 17,654
  • 5
  • 72
  • 110
Jacksonkr
  • 31,583
  • 39
  • 180
  • 284

2 Answers2

1

cancelAllOperations goes through the items in the queue and calls cancel on each one. If you look at the documentation for completionBlock:

The completion block you provide is executed when the value returned by the isFinished method changes to YES. Thus, this block is executed by the operation object after the operation’s primary task is finished or cancelled.

can be seen here

edit:

another snippet from the documentation for setCompletionBlock:

A finished operation may finish either because it was cancelled or because it successfully completed its task. You should take that fact into account when writing your block code. Similarly, you should not make any assumptions about the successful completion of dependent operations, which may themselves have been cancelled.

Dima
  • 23,484
  • 6
  • 56
  • 83
1

Isn't it your responsibility to check isCancelled during your operation's task in case it gets canceled halfway though?

NSOperationQueue won't just kill tasks, it will set them as cancelled and let them finish themselves. This lets you clean up any resources you might have allocated and tidy up before you exit.

Tasks that haven't started yet won't start.

deanWombourne
  • 38,189
  • 13
  • 98
  • 110
  • How can I check `isCancelled` from within my block? I don't have a reference to the operation and `self` has already been "nullified" by this point because I'm getting an `EXC_BAD_ACCESS` in my block when `self` is accessed. – Jacksonkr Jun 19 '12 at 17:28
  • Ah, yes. That's a problem. Though surely your completion handler will already be on the main thread so you don't need the god at all? – deanWombourne Jun 20 '12 at 17:46
  • 1
    "don't need the god at all" I'm not sure what you mean.. Sounds too religious for this convo :) – Jacksonkr Jun 20 '12 at 17:56
  • 1
    Thanks autocorrect! What I meant was you won't need gcd at all! – deanWombourne Jun 27 '12 at 13:08