> I'm using GCD, creating a dispatch queue and want to be able to stop
> the tasks (blocks) from running if the user cancels.
The problem with using a dispatch queue is any tasks already enqueued may have locks etc which then never get released. You really should put a short circuit in you block to do the equivalent of 'if(cancelled) return' so they all turn into no-ops, complete, and then release any holds they have.
Suspending is akin to pausing rather than cancelling; there's an assumption you will resume (shortly) thereafter.
NSOperationQueue allows for this and delegates to GCD when available so sounds like that may be a better fit from what you're describing.
Alex
@alblue
If you use the new NSBlockOperation, you can add as many blocks as you
want to the given operation, and still cancel them out with a -cancel.
Bill
> PSA: It's a good idea to override -(void) cancel in your NSOperation
> subclass. Just wily-nily invoking -cancel on an operation might leak
> some memory.
Not if you design your NSOperation subclass properly, it won't. Anything your operation needs should be retained in -init (or your designated initializer), and released in -dealloc and/or -finalize. That way it doesn't matter if your -main implementation even gets called (or cancelled); you'll still relinquish resources when the operation is deallocated.
The presence of -[NSOperation cancel] isn't a silver bullet; it will not stop a running -main in its tracks; you still need to insert cancellation points by checking [self isCancelled] and taking proper action. So, unless you resort to checking a flag (in this case, one NSOperation defines for you), the entirety of -main will run to completion just like a block submitted to a dispatch queue.
The only time I'd expect overriding -cancel to be necessary is if your -isConcurrent returns YES. If you're managing your own background processing, -cancel might want to do something more interesting than just setting a flag. (However, you should definitely call [super cancel] if you do override it.)
- Paul