如何取消使用 addOperationWithBlock 创建的操作?

发布于 2024-10-16 18:29:31 字数 375 浏览 3 评论 0原文

我正在使用 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 是更好的方法吗?

I'm using NSOperationQueue's addOperationWithBlock. From within the block, how do I check to see if I'm supposed to cancel the operation? Or access any NSOperation properties/methods?

[myOperationQueue addOperationWithBlock: ^{

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

  }

}];

Is the better way to do this to use a NSBlockOperation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

回心转意 2024-10-23 18:29:31

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

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

[[self queue] addOperation:operation];

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

A better solution might be to use NSBlockOperation and add that to the queue instead of a raw block. You could do something like:

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

[[self queue] addOperation:operation];

This lets you use blocks while giving you a little more control over the operation... and a few more NSOperation niceties as well (like the ability to add completion blocks, for example).

嘿哥们儿 2024-10-23 18:29:31

如果操作位于块中,您无法真正检查是否需要取消该操作。如果它在一个块中并且应该被取消,那么它就会被取消。无法访问 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 来完成此操作。

You can't really check to see if you need to cancel the operation if it's in a block. If it's in a block and it's supposed to be canceled then it is canceled. Accessing NSOperation properties is not possible because the block is not an NSOperation instance per se.

Example code:

#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;
}

If you remove the cancelAllOperations call then the blocks fire as you would expect.

I would suggest that if you need to have finer grained control over the operation's cancel state and interplay with the NSOperationQueue that you would be better off using an NSOperation rather than an NSBlockOperation. You can subclass NSOperation to accomplish this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文