I have some NSOperation
s in a dependency graph:
NSOperation *op1 = ...;
NSOperation *op2 = ...;
[op2 addDependency:op1];
Here's how I'm running them:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:op1];
[queue addOperation:op2];
Now I need to cancel them. How do I ensure that all the NSOperation
s in a dependency graph are cancelled, and that no other NSOperation
s are cancelled?
what I've tried:
Calling cancel
on either NSOperation
doesn't cancel the other (as far as I can tell):
[op1 cancel]; // doesn't cancel op2
// -- or --
[op2 cancel]; // doesn't cancel op1
Cancelling the queue would also cancel operations that aren't part of the dependency graph of op1
and op2
(if there are any such operations in the queue):
[queue cancelAllOperations];
So I solved this using a custom method that recursively looks through an NSOperation
's dependencies and cancels them. However, I'm not happy with this solution because I feel like I'm fighting the framework:
- (void)recursiveCancel:(NSOperation *)op
{
[op cancel];
for (NSOperation *dep in op.dependencies)
{
[self recursiveCancel:op];
}
}
you use cancel , and test whether self (the NSOperation ) has been cancelled during execution.
If you just want to cancel a specific Operation , then you can call the cancel method. If, on the other hand, you wish to cancel all operations that are in an operation queue, then you should call the cancelAllOperations method defined on OperationQueue .
You can safely use a single NSOperationQueue object from multiple threads without creating additional locks to synchronize access to that object. Operation queues use the Dispatch framework to initiate the execution of their operations.
An abstract class that represents the code and data associated with a single task.
Sounds to me like you are trying to group operations together in the same queue. To achieve that it's best to split them up using a queue per group. So for each group create an NSOperation subclass in concurrent mode, include a queue, add each sub-operation to the queue. Override cancel and call [super cancel] then [self.queue cancelAllOperations].
A huge advantage of this approach is you can retry operations by adding again to the sub-queue, without affecting the order of the main queue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With