在异步线程中与异步同步

时间:2016-01-24 16:34:55

标签: ios asynchronous nsoperation synchronous

最近,我正在快速学习并发。根据苹果在NSOperation class reference中的文件:

  

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

是否意味着在单独的线程中同步与异步相同?当我使用以下代码进行测试时,操作确实不会阻止当前主线程。

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

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

2 个答案:

答案 0 :(得分:2)

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

NSOperation相对较旧(在iOS术语中;在ObjC术语中相当现代)。它是在OS X 10.5中添加的。在OS X 10.6 / iOS 4之前,没有NSBlockOperation个对象。根本没有街区。因此,进行操作的唯一方法是子类化或使用NSInvocationOperation。这两种方法都很麻烦,但比直接使用NSThread的旧方法更容易,更强大。

(当多核成为一个东西时,这是正确的.10.5以添加核心动画而闻名,我认为它是Cocoa中第一个主要的抢先式多任务框架。在10.5之前,大多数事情都是通过runloop和合作完成的。多任务处理,对于单核系统来说实际上是非常有效和高效的。但它不能很好地扩展到多核系统。像NSOperation这样的工具可以帮助我们编写更好的多核代码,但是GCD非常强大,它完全支配了多任务代码在Cocoa中的编写方式。)

当您继承NSOperation时,您需要告诉系统您的操作是否是异步的。这不是异步运行您的请求。这是您的start方法不会阻止的承诺。它取决于你的start方法,以确保操作真的是异步的。

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

自引入街区以来,它变得更加无关紧要。使用NSBlockOperation(或dispatch_async)而不是子类NSOperation几乎总是容易得多,这对于完全正确而言总是有点棘手。

万一你还没有读过它,如果你想学习Cocoa并发,你肯定想从Concurrency Programming Guide开始。

答案 1 :(得分:1)

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

如果线程B依次将请求转移到线程C,使得线程B能够在线程C运行请求时执行其他工作,则第二个请求是与线程B相对的异步。

当然,一次又一次地异步地保持农业的相同元素是没有意义的。但是假设上面描述的线程A委托给线程B的工作可以分成多个较小的工作元素。线程B在线程C,D等上异步调用那些较小的工作元素是合理的。如果B向A提供服务使得A不希望/不需要知道工作方式的详细信息,则可能会发生这种情况。完成;它只是想要异步完成工作。 B知道细节,可以决定是否/如何通过较小的并行单元完成工作。