2011-02-10 22 views
17

我正在使用NSOperationQueue的addOperationWithBlock。从该区块内,我该如何检查是否应取消操作?或者访问任何NSOperation属性/方法?如何取消用addOperationWithBlock创建的操作?

[myOperationQueue addOperationWithBlock: ^{ 

    while (/* long running loop */) 
    { 
     // how to determine here if I need to cancel? 
     // for that matter, access any NSOperation properties/methods? 

    } 

}]; 

更好的方法来做到这一点使用NSBlockOperation?

回答

49

更好的解决方案可能是使用NSBlockOperation并将其添加到队列而不是原始块。你可以这样做:

__block NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ 
    while(![operation isCancelled]){ 
    //Some long operation 
    } 
}]; 

[[self queue] addOperation:operation]; 

,就可以使用块,而让你在操作一点点更多的控制......和一些更细微NSOperation以及(如添加完成块,例如能力)。

+0

这几乎就是我想要的。但它只适用于该特定的区块。在我的情况下,我的块调用另一个功能,另一个块,在那一点上,我不认为我有权访问'操作'了。我认为我的情况将起作用的唯一方法是如果我分类NSOperation。 – roocell 2012-11-21 15:56:06

2

如果您需要在块中取消操作,则无法真正检查该操作。如果它在一个区块中,它应该被取消,那么它将被取消。访问NSOperation属性是不可能的,因为该块本身不是NSOperation实例。

示例代码:

#import <Foundation/Foundation.h> 

int main (int argc, const char * argv[]) 
{ 

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    NSOperationQueue *q = [[NSOperationQueue alloc] init]; 
    [q addOperationWithBlock:^{ 
     [NSThread sleepForTimeInterval:10]; 
     NSLog(@"Block 1"); 
    }]; 
    [q addOperationWithBlock:^{ 
     [NSThread sleepForTimeInterval:3]; 
     NSLog(@"Block 2"); 
    }]; 
    [q cancelAllOperations]; 
    [NSThread sleepForTimeInterval:15]; 

    [pool drain]; 
    return 0; 
} 

如果删除cancelAllOperations然后调用块火象你所期望的。

我会建议,如果你需要更细粒度地控制操作的取消状态和与NSOperationQueue的相互作用,你最好使用NSOperation而不是NSBlockOperation。您可以继承NSOperation来完成此操作。