2016-01-24 163 views
3

最近,我正在学习并发在迅速。根据苹果的文档中NSOperation class reference是在异步同步异步

当你添加一个操作到操作队列,队列会忽略异步属性的值,并总是调用从一个单独的线程启动方法。因此,如果您始终通过将操作添加到操作队列来运行操作,则没有理由使它们异步。

是不是意味着同步在一个单独的线程中是异步的?当我用下面的代码进行测试时,操作确实不会阻塞当前的主线程。

let operationQueue = NSOperationQueue() 
let operation = NSBlockOperation(){ 
    //do some task here 
} 
operationQueue.addOperation(operation) 

所以如果它是真的,那么我们为什么要创建NSOperation的并发子类呢?

回答

1

异步总是相对于发出请求的线程定义的。因此,如果线程A在线程B中运行请求,以便线程A能够在线程B运行请求时执行其他工作,则请求与线程A是异步的。

如果反过来农场线程B出请求线程C-使得线程B能够同时线程C-运行请求做其他工作,然后该第二请求是异步相对于螺纹B.

它当然,不要一次又一次地反复地重复同样的工作元素。但是,假设上述线程A委托给线程B的工作可以分解为多个较小的工作元素。线程B在线程C,D等上异步调用这些较小的工作元素是合理的。如果B向A提供服务使得A不想/不需要知道工作的细节完成;它只是想要异步完成工作。 B知道细节,并可以决定是否/如何通过较小的并联装置完成工作。

2

哦,NSOperation。你有这样奇怪的历史。

NSOperation相对较旧(用iOS术语来说;在ObjC术语中相当现代)。它被添加到OS X 10.5中。在OS X 10.6/iOS 4之前,没有NSBlockOperation对象。根本没有任何障碍。所以做手术的唯一方法是继承或使用NSInvocationOperation。两种方法都很麻烦,但比直接使用NSThread的旧方法更容易和更强大。 (这是正确的时候,多核心成为了一件事情,10.5着名的是增加了Core Animation,这是我相信Cocoa中第一个主要的抢先式多任务框架。在10.5之前,大多数事情都是通过runloop来完成的,协同式多任务,这对于单核系统来说实际上是非常有效和高效的,但是它并没有很好地适应多核系统,提供了像NSOperation这样的工具来帮助我们编写更好的多核代码,但是GCD是,所以功能更强大,它完全支配Cocoa中多任务代码的编写方式)。

当您将NSOperation子类化时,您需要告诉系统您的操作是否为asy nchronous。这不是异步运行你的请求。这是承诺您的start方法不会阻止。这取决于您的start方法以确保操作确实是异步的。

这只是在您的NSOperation正在手动启动的情况下才需要,即使此时通常不需要。如果你把它放到NSOperationQueue(你真的应该总是这样做),这个属性是无关紧要的。我记得当时造成了很多混乱。

自引入块以来,它变得更加无关紧要。使用NSBlockOperation(或dispatch_async)几乎总是比使用子类NSOperation容易得多,因为要得到正确的结果总是有点棘手。

为防万一你还没有读过它,如果你想研究Cocoa并发性,你一定要从Concurrency Programming Guide开始。

+0

真的很感谢。如果我理解正确,你的意思是同步在一个单独的线程确实是异步。实际上,使用'NSOperationQueue'时不需要改变异步属性。 – rrrain

+0

两个计数都正确。 –