Reputation: 1284
I need to cancel all operation in operationqueue. but after call cancellAllOperation method, operations is still running. simple example:
@interface MyOperation : NSOperation
@end
@implementation MyOperation
-(void)main {
NSLog(@"starting 1");
sleep(4);
NSLog(@"finished 1");
}
@end
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
MyOperation *op = [MyOperation new];
[queue addOperation:op];
sleep(2);
[queue cancelAllOperations];
NSLog(@"canceled");
}
log:
2014-07-23 09:55:48.839 MDict1[837:1303] starting 1
2014-07-23 09:55:50.842 MDict1[837:70b] canceled
2014-07-23 09:55:52.842 MDict1[837:1303] finished 1
Upvotes: 2
Views: 778
Reputation: 318864
Canceling an operation won't wake up the sleep
call. And calling sleep
in viewDidLoad
is BAD. Never sleep on the main thread.
The proper solution is that the implementation of your operation's main
method needs to check if self
has been cancelled. If so, it needs to return.
One rough example might be:
- (void)main {
while (!self.isCancelled) {
// do some repeated operation
}
}
Again, it is the responsibility of the operation to stop itself when it sees that it has been cancelled. The queue doesn't actually kill any operations.
From the docs for NSOperationQueue cancelAllOperations
(emphasis mine):
This method sends a cancel message to all operations currently in the queue. Queued operations are cancelled before they begin executing. If an operation is already executing, it is up to that operation to recognize the cancellation and stop what it is doing.
Upvotes: 1