Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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(filterContentForSearchText:)
                                                                   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;
}
like image 238
fabian789 Avatar asked Feb 26 '23 13:02

fabian789


1 Answers

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.

like image 132
Justin Spahr-Summers Avatar answered Mar 03 '23 02:03

Justin Spahr-Summers