开发者

Cancel NSOperation in for loop?

开发者 https://www.devze.com 2023-01-31 17:38 出处:网络
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:

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消