从NSOperationQueue运行的NSOperation是什么意思?

时间:2013-08-21 11:07:50

标签: ios nsoperation nsoperationqueue

因为NSOperationQueue总是在新线程上运行任务, 当isConcurrentNSOperation开始运行时,我对NSOperationQueue的作用感到困惑。

如果我有两个NSOperation子类,两个都运行异步进程,则都从NSOperationQueue启动,并且我都覆盖isCancelledisExecuting,{{1 }和isFinished。 如果我在isReady总是isConcurrent而另一个总是return YES,则会有什么不同。

谁实际致电return NO?逻辑如果变为isConcurrentNO

3 个答案:

答案 0 :(得分:5)

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

来自doc

  

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

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

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

的文件
  

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

答案 1 :(得分:2)

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


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

我读了这句话:

  

在OS X v10.6及更高版本中,操作队列忽略返回的值   这个方法总是在一个单独的线程上开始操作。

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

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

我也误解了原来的问题,作为关于并发操作和isConcurrent标志的更一般的问题,并且接受的答案实际上是

  

自10.6和iOS 4

以来,isConcurrent标志可以被忽略

我不确定这是否正确。

如果我现在理解原始问题,请解释:

  

鉴于正确构建的并发NSOperationisConcurrent标志本身是否实际上改变了操作的执行?

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

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

  2. 文档始终指的是必需的方法 覆盖。

  3. 或许isConcurrent实际上已被弃用,但由于它只是一个BOOL标志,因此在文档中弃用它可能不值得。或者它现在可能没有任何作用,但Apple已将其保留以备将来使用,并希望您按照描述覆盖它。

    我创建了一个快速测试项目NSOperation仅覆盖isConcurrentmainisConcurrent在任何阶段都未被调用。这是一个非常简单的测试。我猜你也可能测试过了吗?我想假设NSOperationQueue没有调用NSOperation's start的默认实现。

    那么我们离开了哪里?显然,实现它并返回YES以满足记录的要求并不困难。然而,从我的角度来看,我认为从10.6和iOS 4.0的警告中说,现在可以安全地忽略它是太过分了。


    我原来的答案......

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

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

    一个常见示例是管理NSOperation的{​​{1}}。 NSURLConnection拥有自己在后台运行的机制,因此不需要NSURLConnection并发。

    一个显而易见的问题是:“为什么将已经并发的操作放入NSOperationQueue?”因此,操作可以受益于NSOperationQueue类似依赖项等的其他功能。

    文档中的误导性部分仅指的是调用NSOperationQueue的{​​{1}}方法的线程。这一变化引发了QA1712中讨论的问题。

答案 2 :(得分:0)

将原始问题解释为:

  

如果正确构建并发NSOperationisConcurrent返回的值是否实际上会改变操作的执行?

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

该标志的目的仅描述为:

  

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

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


附加说明:

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

  

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

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

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

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