iOS之多线程NSOperation

目前在 iOS 和 OS X 中有两套先进的同步 API 可供我们使用:NSOperation 和 GCD 。其中 GCD 是基于 C 的底层的 API ,而 NSOperation 则是 GCD 实现的 Objective-C API。

1. 什么时候使用NSOperationQueue而不是GCD

比如你可能写过类似这样的代码(这样来请求网络数据):

 1 dispatch_async(_Queue, ^{
 2   
 3   //请求数据
 4   NSData *data = [NSData dataWithContentURL:[NSURL URLWithString:@"http://domain.com/a.png"]];
 5 
 6     dispatch_async(dispatch_get_main_queue(), ^{
 7 
 8          [self refreshViews:data];
 9     });
10 });

它是可以正常的工作,但是有个致命的问题:这个任务是无法取消的 dataWithContentURL:是同步的拉取数据,它会一直阻塞线程直到完成请求,如果是遇到了超时的情况,它在这个时间内会一直占有这个线程;在这个期间并发队列就需要为其他任务新建线程,这样可能导致性能下降等问题。

操作队列(operation queue)是由 GCD 提供的一个队列模型的 Cocoa 抽象。GCD 提供了更加底层的控制,而操作队列则在 GCD 之上实现了一些方便的功能,这些功能对于 app 的开发者来说通常是最好最安全的选择。NSOperationQueue相对于GCD来说有以下优点:

  • 提供了在 GCD 中不那么容易复制的有用特性。
  • 可以很方便的取消一个NSOperation的执行
  • 可以更容易的添加任务的依赖关系
  • 提供了任务的状态:isExecuteing, isFinished.

名词: 上面提到的 “任务”, “操作” 即代表要再NSOperation中执行的事情。

NSOperation和NSOperationQueue实现多线程的具体步骤

先将需要执行的操作封装到一个NSOperation对象中

然后将NSOperation对象添加到NSOperationQueue中

系统会自动将NSOperationQueue中的NSOperation取出来

将取出的NSOperation封装的操作放到一条新线程中执行

NSOperation是个抽象类,并不具备封装操作的能力,必须使用它的子类

 使用NSOperation子类的方式有3种

NSInvocationOperation(默认情况下,调用了start方法后并不会开一条新线程去执行操作,而是在当前线程同步执行操作,只有将NSOperation放到一个NSOperationQueue中,才会异步执行操作)

NSBlockOperation(只要NSBlockOperation封装的操作数 > 1,即便没有添加到NSOperationQueue中也会异步执行操作)

自定义子类继承NSOperation,实现内部相应的方法

原文地址:https://www.cnblogs.com/H7N9/p/4896780.html