6

因为NSOperationQueue总是在新线程上运行任务,所以我对isConcurrentwhen run NSOperationfrom的角色感到困惑NSOperationQueue

如果我有两个 的子类NSOperation,它们都运行异步进程,则两者都是从NSOperationQueue我覆盖isCancelled的,并且在两者中启动isExecuting的。如果一个我覆盖到 always而另一个总是覆盖到会有什么区别。isFinishedisReadyisConcurrentreturn YESreturn NO

究竟是谁打电话isConcurrent?如果是NO或,逻辑如何变化YES

4

3 回答 3

5

这是一种遗留方法,在 OS X v10.6 和 iOS 4 之前使用,即在引入 GCD 进行NSOperationQueue调度之前。

文档

操作队列通常提供用于运行其操作的线程。在 OS X v10.6 及更高版本中,操作队列使用libdispatch库(也称为 Grand Central Dispatch)来启动其操作的执行。因此,操作总是在单独的线程上执行,无论它们被指定为并发操作还是非并发操作。然而,在 OS X v10.5 中,只有当它们的方法返回时,操作才会在单独的线程上执行isConcurrentNO。如果该方法返回 YES,则操作对象应创建自己的线程(或启动一些异步操作);队列没有为它提供线程。

如果您运行的是 OS X >= 10.6 或 iOS >= 4,您可以放心地忽略它。

作为对这一事实的确认,来自isConcurrent

在 OS X v10.6 及更高版本中,操作队列忽略此方法返回的值,并始终在单独的线程上启动操作。

于 2013-08-21T11:28:54.500 回答
2

我现在添加了一个更简洁的答案,暂时留下这个,因为它是讨论的一部分......


isConcurrent好的,直到今天我对使用该方法感到非常满意!

我读了一句话:

在 OS X v10.6 及更高版本中,操作队列忽略此方法返回的值,并始终在单独的线程上启动操作。

作为与 QA1712 相关的警告,指出对于并发操作,该start方法现在可以在与排队操作的线程不同的线程上调用,这是 10.6 和 iOS 4 中的更改。

我没有读到这表明该isConcurrent方法被队列完全忽略并且根本没有任何目的,只是它不再影响start被调用的线程。我可能误解了这一点。

我还将原始问题误解为关于并发操作和isConcurrent标志的更普遍的问题,而接受的答案实际上是在说

isConcurrent从 10.6 和 iOS 4 开始可以忽略该标志

我不确定这是否正确。

如果我现在理解原来的问题,可以解释一下:

给定一个正确构建的并发NSOperationisConcurrent标志本身是否真的改变了操作的执行?

我想很难说所有可能的设置,但我们可以这样说:

  1. 它没有被弃用。Apple 弃用不再有用的方法是正常的。

  2. 文档一致地提到该方法是必需的覆盖。

也许isConcurrent已被有效弃用,但由于它只是一个BOOL标志,因此在文档中弃用它可能不值得。或者它现在什么都不做,但 Apple 保留了它以备将来使用,并希望您按照描述覆盖它。

我创建了一个快速测试项目,该项目被NSOperation覆盖,isConcurrent并且在任何阶段都没有被调用。这是一个非常简单的测试。我想你可能也测试过它?我假设如果没有将其称为可能的默认实现。mainisConcurrentNSOperationQueueNSOperation'sstart

那么,我们将何去何从?显然,实施它并返回YES以满足记录的要求是没有问题的。然而,从我的角度来看,我认为从关于 10.6 和 iOS 4.0 的警告说现在可以安全地忽略它是一个太大的飞跃。


我的原始答案...

isConcurrent不是遗留方法,也不会被NSOperationQueue. 其他答案中引用的文档有点不清楚,很容易被误解。

isConcurrent = YES表示操作提供了自己的并发方式。或者换句话说,操作"isAlreadyConcurrent"并不需要NSOperationQueue提供和管理并发。由于NSOperationQueue不再提供并发性,您需要告诉它何时操作isFinished或是否isCancelled(等)因此需要覆盖这些方法。

一个常见的例子是NSOperation管理NSURLConnection. NSURLConnection有自己的后台运行机制,所以不需要由NSOperationQueue.

那么一个明显的问题是:“为什么将已经并发的操作放入一个NSOperationQueue?” 这样操作可以从NSOperationQueue类似依赖项等的其他功能中受益。

文档的误导部分仅指调用startan 方法的线程NSOperation。该更改导致了 QA1712 中讨论的问题。

于 2013-08-21T21:40:44.593 回答
0

将原始问题解释为:

给定一个正确构建的并发NSOperation,返回的值是否isConcurrent真的改变了操作的执行?

虽然我们可以尝试了解isConcurrent标志是如何被NSOperationNSOperationQueue或操作系统的其他部分使用的,但依赖我们发现的任何信息都是错误的。

该标志的用途仅描述为:

如果操作相对于当前线程异步运行,则返回 YES,如果操作在启动它的任何线程上同步运行,则返回 NO。

只要您正确响应,谁调用该方法或它如何影响 Apple 框架内的任何逻辑都应该不重要。


补充笔记:

该文档确实提到了NSOperationQueue在 OSX 10.6 和 iOS 4.0 之前和之后使用此值的方式的更改。

在 OS X v10.6 中,操作队列忽略 isConcurrent 返回的值,并始终从单独的线程调用操作的 start 方法。然而,在 OS X v10.5 中,只有当 isConcurrent 返回 NO 时,操作队列才会创建线程。...

此更改导致QA1712中描述的问题。

该注释通常被解释为暗示该isConcurrent标志在 10.6 和 iOS 4 之后不再使用,可以忽略。我不同意这种解释,因为该方法尚未被正式弃用,并且仍被记录为并发操作的必需覆盖。

此外,它的用途在过去发生了变化,这提醒我们将来可能会再次发生变化,因此即使我们怀疑它目前没有任何影响,我们也应该正确回应。

于 2013-08-22T11:40:04.710 回答