这篇文章里我将不过多的谈及理论知识,这些东西会的自然会,不会的,看多了也是云里雾里。下面我讲更多的用代码+注释的方式来讲如何使用NSOperation和NSOperationQueue。

  1、NSOperation。是抽象类,不能够直接使用,而是使用子类NSInvocationOperation和NSBlockOperation来实际执行任务。NSOperation本身和多线程是没有任何关系的,她只是封装了一个代码段和数据去实现一个功能。

  1.1、NSInvocationOperation,基于一个对象和selector来创建操作。看下面的代码:

 - (void)invocationOperation {

     NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(startOpration) object:nil];
[operation setCompletionBlock:^{
NSLog(@"执行完成,是否主线程:%@", [NSThread isMainThread] == ? @"YES" : @"NO");
}];
[operation start]; //启动任务
[operation cancel]; //取消任务
[operation isExecuting]; //任务是否在执行
[operation isFinished]; //任务是否已经结束
} - (void)startOpration {
NSLog(@"开始执行,是否主线程:%@", [NSThread isMainThread] == ? @"YES" : @"NO");
}

  首先是创建了一个operation,并给operation添加了一个需要执行的方法:startOpration。其中Line4中的方法将会在operation执行完成后执行,当然不是必须的,如果需要在operation执行完进行一些操作,可以写上这个方法。

  下面是执行的结果:

-- ::19.577 NSOperation[:] 开始执行,是否主线程:YES
-- ::19.577 NSOperation[:] 执行完成,是否主线程:NO

  根据上面执行的结果,我们可以发现, startOpration 这个方法是在主线程执行的。至于Line4~Line6是在子线程执行的,则不在今天的讨论内容中,略过。

  1.2、NSBlockOperation。相对于NSInvocationOperation,NSBlockOperation则是将selector中需要调用的方法使用Block进行了封装,使用起来更加的方便。关于Block的使用,不明白的同学可以参考我的上一篇博客。

  NSBlockOperation对象能够并发的执行一个或多个Block对象,所有相关的Block都执行完成之后,操作才算完成。下面看代码:

 - (void)blockOperation {
//创建一个操作
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%d,%@,是否主线程:%@", __LINE__, [NSThread currentThread], [NSThread isMainThread] == ? @"YES" : @"NO");
}];
//通过addExecutionBlock方法添加Block操作
[blockOperation addExecutionBlock:^{
NSLog(@"%d,%@,是否主线程:%@", __LINE__, [NSThread currentThread], [NSThread isMainThread] == ? @"YES" : @"NO");
}];
[blockOperation addExecutionBlock:^{
NSLog(@"%d,%@,是否主线程:%@", __LINE__, [NSThread currentThread], [NSThread isMainThread] == ? @"YES" : @"NO");
}];
[blockOperation addExecutionBlock:^{
NSLog(@"%d,%@,是否主线程:%@", __LINE__, [NSThread currentThread], [NSThread isMainThread] == ? @"YES" : @"NO");
}];
[blockOperation addExecutionBlock:^{
NSLog(@"%d,%@,是否主线程:%@", __LINE__, [NSThread currentThread], [NSThread isMainThread] == ? @"YES" : @"NO");
}];
//执行操作
[blockOperation start];
//上面的几个Block是并发执行的,将会在不同的线程中执行,
}

  下面是执行的结果:

-- ::28.585 NSOperation[:] ,<NSThread: 0x7f97cad07c30>{number = , name = main},是否主线程:YES
-- ::28.585 NSOperation[:] ,<NSThread: 0x7f97cae223c0>{number = , name = (null)},是否主线程:NO
-- ::28.585 NSOperation[:] ,<NSThread: 0x7f97cac0eb60>{number = , name = (null)},是否主线程:NO
-- ::28.586 NSOperation[:] ,<NSThread: 0x7f97cad07c30>{number = , name = main},是否主线程:YES
-- ::28.585 NSOperation[:] ,<NSThread: 0x7f97cad06530>{number = , name = (null)},是否主线程:NO

  可以从上面的执行结果中,很容易的发现,程序是并行的执行。而创建的操作,也就是:Line4是在主线程中执行,而其他通过通过 addExecutionBlock 方法添加的Block操作则是在不同的线程中执行。

  通过上面的说明,我要总结的是:NSOperation以及子类,只是一个操作,本身无主线程和子线程的区分,可以在任意线程中使用。也就是,在主线程中创建的操作将在主线程中执行,在子线程中创建的操作将在子线程中执行。而实现多线程可以配合NSOperationQueue来实现。下面来介绍NSOperationQueue。

  2.NSOperationQueue,是操作队列,它用来管理一组NSOperation对象的执行,会根据需要自动为NSOperation对象开辟适合数量的线程,以完成任务的并行执行。下面上代码:

 - (void)operationQueue {
//创建一个任务队列,alloc(new)出来的任务队列将会在子线程中执行,并且是并发执行
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//创建操作NSInvocationOperation
for (int i = ; i < ; i++) {
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(startOpration) object:nil];
[queue addOperation:operation];
}
//创建NSBlockOperation操作
for (int i = ; i < ; i++) {
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%d,%@,%d", __LINE__, [NSThread currentThread], [NSThread isMainThread]);
}];
//将操作添加到队列中
[queue addOperation:blockOperation];
}
//设置最大并发数,当把最大并发数设置1时,此时队列相当于串行执行。
queue.maxConcurrentOperationCount = ;
//添加依赖关系
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"这是任务1,依赖于任务2");
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"这是任务2");
}];
//添加依赖关系
//添加依赖关系时,注意不能添加互相依赖,如A依赖B,B依赖A
[op1 addDependency:op2];
//添加依赖关系必须在任务添加到队列之前设置
[queue addOperation:op1];
[queue addOperation:op2];
//回到主线程的操作
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@"%d,%@,%d", __LINE__, [NSThread currentThread], [NSThread isMainThread]);
}];
}

  下面是执行的结果:

 -- ::11.625 NSOperation[:] 开始执行,是否主线程:NO
-- ::11.625 NSOperation[:] 开始执行,是否主线程:NO
-- ::11.625 NSOperation[:] 开始执行,是否主线程:NO
-- ::11.625 NSOperation[:] 开始执行,是否主线程:NO
-- ::11.625 NSOperation[:] 开始执行,是否主线程:NO
-- ::11.626 NSOperation[:] ,<NSThread: 0x7f852bc099f0>{number = , name = (null)},
-- ::11.627 NSOperation[:] ,<NSThread: 0x7f852bf0db10>{number = , name = (null)},
-- ::11.628 NSOperation[:] ,<NSThread: 0x7f852bc46ee0>{number = , name = (null)},
-- ::11.628 NSOperation[:] ,<NSThread: 0x7f852bc4fe00>{number = , name = (null)},
-- ::11.628 NSOperation[:] ,<NSThread: 0x7f852be0a130>{number = , name = (null)},
-- ::11.629 NSOperation[:] 这是任务2
-- ::11.629 NSOperation[:] 这是任务1,依赖于任务2
-- ::11.631 NSOperation[:] ,<NSThread: 0x7f852bd05190>{number = , name = main},

  从上面的执行结果中,我们可以得到几个结论:1.首先队列中的任务都是在子线程中执行的;2.队列中的任务是并发执行的。而常用到的添加依赖关系,以及操作完成之后回到主线程的方法在上面的代码中都有体现。

  需要说明的是,一旦将operation添加到队列中后,队列就拥有了这个操作,操作将不能从队列中删除,只能取消一个操作,或者取消所有的操作。取消一个操作的方法:

[operation cancel];

  取消所有操作的方法:

[queue cancelAllOperations];

  如果想要暂停操作的执行可以使用方法: [queue setSuspended:YES]; 来实现。但是暂停不会导致正在执行的操作被暂停,只会阻止队列调度新的操作执行。可以通过方法: [queue setSuspended:NO]; 来继续队列的执行。

  3、最后做一个简单的总结。NSInvocationOperation 和 NSBlockOperation的功能是开启一个线程任务,这个线程任务处于子线程和主线程取决于线程任务是在哪个线程中开辟的。这些任务可以使用线程任务队列NSOperationQueue来管理,当new一个队列时,队列所管理的任务都在子线程中执行.当使用[NSOperationQueue mainQueue]时,队列管理的任务在主线程中执行。

  以上就是这篇文章的多有内容,如果有不对或者不足的地方,请大家在评论中指出,大家一起讨论。

多线程之NSOperation和NSOperationQueue的更多相关文章

  1. iOS多线程之NSOperation,NSOperationQueue

    使用 NSOperation的方式有两种, 一种是用定义好的两个子类: NSInvocationOperation 和 NSBlockOperation. 另一种是继承NSOperation 如果你也 ...

  2. iOS多线程之NSOperation和NSOperationQueue的使用

    一:NSOperation 两个子类+重写main方法 NSInvocationOperation NSBlockOperation 有个类方法 BlockOprationWith: 还有就是自己个子 ...

  3. 多线程之NSOperation

    关于多线程会有一系列如下:多线程之概念解析 多线程之pthread, NSThread, NSOperation, GCD 多线程之NSThread 多线程之NSOperation 多线程之GCD

  4. iOS多线程之NSOperation详解

    使用NSOperation和NSOperationQueue进行多线程开发,只要将一个NSOperation(实际开发中需要使用其子类 NSInvocationOperation,NSBlockOpe ...

  5. iOS-多线程之NSOperation

    前言 这篇文章主要讲NSOperation的使用. What 使用NSOperation和NSOperationQueue进行多线程开发类似于线程池,只要将一个NSOperation(实际开发中需要使 ...

  6. IOS多线程之NSOperation学习总结

    NSOperation简介 1.NSOperation的作用 配合使用NSOperation和NSOperationQueue也能实现多线程编程 2.NSOperation和NSOperationQu ...

  7. iOS 多线程之NSOperation篇举例详解

    这篇博客是接着总篇iOS GCD NSOperation NSThread等多线程各种举例详解写的一个支篇.总篇也包含了此文的链接.本文讲解的知识点有NSBlockOperationClick,队列, ...

  8. [转] iOS多线程编程之NSOperation和NSOperationQueue的使用

    <iOS多线程编程之NSThread的使用> 介绍三种多线程编程和NSThread的使用,这篇介绍NSOperation的使用. 使用 NSOperation的方式有两种, 一种是用定义好 ...

  9. iOS多线程编程之NSOperation和NSOperationQueue的使用

    前一篇 <iOS多线程编程之NSThread的使用> 介绍三种多线程编程和NSThread的使用,这篇介绍NSOperation的使用. 使用 NSOperation的方式有两种, 一种是 ...

随机推荐

  1. 【转载】两个排序数组的中位数 / 第K大元素(Median of Two Sorted Arrays)

    转自 http://blog.csdn.net/zxzxy1988/article/details/8587244 给定两个已经排序好的数组(可能为空),找到两者所有元素中第k大的元素.另外一种更加具 ...

  2. backbone库学习-Events

    backbone库的框架 http://www.cnblogs.com/nuysoft/archive/2012/03/19/2404274.html 我们先从backbone的Events模块开始 ...

  3. 数据可视化(2)--Justgage

    JustGage 是一个 JavaScript 插件来生成很漂亮的仪表盘,基于 Raphaël 库做向量图绘制. JustGage 完全基于 SVG,因此支持几乎所有浏览器,包括:IE6+, Chro ...

  4. 《微信小程序七日谈》- 第四天:页面路径最多五层?导航可以这么玩

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩 微信小 ...

  5. python面试题大全(二)

    转载请注明出处http://www.cnblogs.com/goodhacker/p/3387027.html 1.python中类方法.类实例方法.静态方法有何区别? 区别: 类方法和静态方法都可以 ...

  6. Hya.io – 基于 Web 的数字音频工作站

    Hya.io 是基于 Web 的音频应用程序,通过 Web MIDI ,音频合成器,音序以及大量的插件来支持硬件 MIDI .您可以添加插件到工作区,将其连接到路由音频,进行播放和实验. HYA 支持 ...

  7. 性能测试类,让你写法代码养成经常测试的好习惯 -ASP.NET C#

    介绍: 可以很方便的在代码里循环执行 需要测试的函数  自动统计出执行时间,支持多线程. 使用方法: PerformanceTest p = new PerformanceTest(); p.SetC ...

  8. lnmp_auto:自动化安装lnmp环境脚本

    朋友找我在一台机器上帮忙安装下discuz.想着搭建过好几次的lnmp了,但是还没有使用过"一键安装"的自动化脚本,去网上有搜索出来,但是运行的时候发现用root运行别人的脚本还是 ...

  9. 通俗易懂的ListView讲解(Adapter、图、实例)

    2016/4/5 17:22] 之前写listview其实写了很多次,但好像还是模模糊糊的感觉,直到今天准备写tab的时候被告诉说原理有像的地方,于是我就先来分析整理一下listview好了   先来 ...

  10. [ASP.NET]谈谈REST与ASP.NET Web API

    13天的假期结束,赶紧回来充电了 本节目录 Web API简介 自我寄宿 IIS寄宿 调用Web API Web API原理 Web API简介 REST REST是“REpresentational ...