18

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

[myOperationQueue addOperationWithBlock: ^{

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

  }

}];

更好的方法是使用 NSBlockOperation 吗?

4

2 回答 2

51

更好的解决方案可能是使用NSBlockOperation并将其添加到队列而不是原始块。您可以执行以下操作:

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

[[self queue] addOperation:operation];

这使您可以在使用块的同时对操作有更多的控制......以及更多的NSOperation细节(例如添加完成块的能力)。

于 2011-11-13T17:13:16.907 回答
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 来完成此操作。

于 2011-06-07T14:12:26.747 回答