Cancel NSOperation in for loop?
I am trying to implement search on a background thread using NSOperation
on iOS
. I didn't want to subclass NSOperation
so this is what I'm doing:
[searchQueue cancelAllOperations];
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self
elector:@selector(filter开发者_StackOverflow中文版ContentForSearchText:)
object:self.searchDisplayController.searchBar.text];
[searchQueue addOperation:op];
[op release];
The search method includes a for loop that checks whether what is being searched is in an array. Now when I cancel the NSOperation
by calling cancelAllOperations
, the for loop continues to run through the array. I would like to prevent this and was wondering whether it is legit to call this from within the for loop:
if ([[[searchQueue operations] objectAtIndex:0] isCancelled]) {
[tmp_array release]; // tmp_array is used to hold temporary results
[pool drain]; // pool is my autorelease pool
return;
}
One of the reasons to subclass NSOperation
is to implement proper cancellation. You could do your approach, but it violates several good design principles. Basically, since cancellation requires the cooperation of the operation itself, NSInvocationOperation
isn't built to cancel the invocation while it's already executing (though it can be successfully cancelled before it starts executing), as the running method shouldn't know anything about how it's called.
Instead, if you subclass NSOperation
, you can put most of this functionality into the main
method very easily:
@implementation MyOperation
- (void)main {
if ([self isCancelled])
return;
for (...) {
// do stuff
if ([self isCancelled]) {
[tmp_array release];
return;
}
}
}
@end
Note also that you don't have to maintain your own autorelease pool with such an implementation.
精彩评论