【问题标题】:How can I cancel an NSOperation in the same thread that the operation?如何在操作所在的同一线程中取消 NSOperation?
【发布时间】:2012-01-24 15:43:12
【问题描述】:

当我取消 NSOperation(当用户按下按钮时)时,会从主线程调用取消方法,但显然该操作正在另一个线程中运行。 因此,为了避免在更改 _isExecuting 和 _isFinished 时出现竞争条件,我认为取消(或至少其逻辑)应该从与 NSOperation 相同的线程调用。除此之外,当用户取消它时,会删除几个文件并且需要时间。因为取消是从主线程调用的,所以所有应用都会有一段时间没有响应,这很丑。

如何在当前 NSOperation 所在的线程中执行取消代码?

我在 cancel 中尝试过这个(类似于我在 ASIHTTPRequest 中看到的):

if (_operationThread) {
    [self performSelector:@selector(cancelOnRequestThread) onThread:_operationThread withObject:nil waitUntilDone:NO];
} else {
    [self cancelOnRequestThread];
}

并且 _operationThread 在 start 方法中使用: _operationThread=[NSThread currentThread];

但它不起作用。

有什么想法或建议吗?

注意:我使用并发操作,所以我使用 start 而不是 main。

非常感谢您的帮助。 里卡多。

【问题讨论】:

    标签: iphone objective-c ios nsoperation nsoperationqueue


    【解决方案1】:

    从主线程调用 NSOperation 上的取消是可以的。 cancel 方法是线程安全的。

    这不应该在你的主线程上造成任何阻塞,因为取消方法本身不应该做任何工作。如果您已经覆盖了删除文件等操作的取消方法,那么这是错误的方法。您不应该重写 cancel 方法,而只需在操作的 main 方法(例如,在任何紧密循环内)的常规点检查 isCancelled 方法,然后如果 isCancelled 返回 YES 则从 main 提早返回,然后将取消相同的操作线程作为执行的其余部分。

    如果您已经采用这种方式实现了它并且仍然遇到性能问题,那么您的操作是否可能根本没有真正在后台线程上运行?例如,如果您已将其添加到 [NSOperationQueue mainQueue] 返回的队列中,那么它实际上是在主应用程序线程上运行的。

    【讨论】:

      猜你喜欢
      • 2012-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多