我有一个很长的循环,我想在后台运行一个 NSOperation 。我想使用一个块:

NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
   while(/* not canceled*/){
      //do something...
   }
}];

问题是,我如何检查它是否被取消。该块不接受任何参数,并且 operation 在它被块捕获时为零。有没有办法取消块操作?

最佳答案

多。亲爱的 future 谷歌员工:当然,operation 在被块复制时为零,但不必复制。它可以用 __block 限定,如下所示:

//THIS MIGHT LEAK! See the update below.
__block NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
   while( ! [operation isCancelled]){
      //do something...
   }
}];

更新:

经过进一步的思考,我发现这将在 ARC 下创建一个保留循环。在 ARC 中,我相信 __block 存储被保留。如果是这样,我们就有麻烦了,因为 NSBlockOperation 还保留了对传入块的强引用,现在它对操作具有强引用,该操作对传入块具有强引用,这......

它不太优雅,但使用显式弱引用应该打破循环:
NSBlockOperation *operation = [[NSBlockOperation alloc] init];
__weak NSBlockOperation *weakOperation = operation;
[operation addExecutionBlock:^{
   while( ! [weakOperation isCancelled]){
      //do something...
   }
}];

任何对更优雅的解决方案有想法的人,请发表评论!

关于objective-c-blocks - 如何取消 NSBlockOperation,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8113268/

10-14 14:23