NSOpertation是一套OC的API,是对GCD进行的Cocoa抽象。

NSOperation有两种不同类型的队列,主队列和自定义队列。

主队列运行于主线程上,自定义队列在后台运行。

【NSBlockOperation】

通过Block创建任务,下面比较主队列和自定义队列的区别:

将自定义队列声明为成员变量,并进行初始化:

@property (nonatomic, strong) NSOperationQueue *myqueue;
self.myqueue = [[NSOperationQueue alloc] init];

获取主队列的方法为[NSOperationQueue mainQueue]。

队列有一个方法addOperationWithBlock方法用于添加一个用Block描述的任务。

具体代码为:

- (void)NSBlockOperation{// 自定义队列在子线程中运行。[self.myqueue addOperationWithBlock:^{NSLog(@"%@",[NSThread currentThread]);}];// 主队列任务在主线程中运行。[[NSOperationQueue mainQueue] addOperationWithBlock:^{NSLog(@"%@",[NSThread currentThread]);}];}

执行这个方法,得到的结果如下,可见与上面的描述相符。

2015-02-17 10:46:15.308 NSOpertaion[709:17138] <NSThread: 0x7b9aa440>{number = 2, name = (null)}
2015-02-17 10:46:15.319 NSOpertaion[709:17067] <NSThread: 0x7b978550>{number = 1, name = main}

【NSInvocationOperation】

需要定义一个回调方法,好处是可以接收一个id类型的object作为消息。

例如:

- (void)NSInvocationOperation{NSDictionary *msg = @{@"name" : @"op",@"message" : @"hello"};NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(InvocationCall:) object:msg];[self.myqueue addOperation:op];}

实现回调方法:

- (void)InvocationCall:(id)obj{NSLog(@"%@ with object %@",[NSThread currentThread],obj);
}

调用后,打印的结果如下,可以看到object对象被传了过来。

2015-02-17 10:56:03.764 NSOpertaion[812:26537] <NSThread: 0x7ba6eb10>{number = 2, name = (null)} with object {message = hello;name = op;
}

【任务执行顺序】

在默认情况下,自定义队列是并行队列,执行无序;而主队列为串行队列,有序执行。下面进行实验验证说法:

    // 自定义队列在子线程中运行。for (int i = 0; i < 9; i++) {[self.myqueue addOperationWithBlock:^{NSLog(@"%@ with no %d",[NSThread currentThread],i);}];}// 主队列任务在主线程中运行。for (int i = 0; i < 9; i++) {[[NSOperationQueue mainQueue] addOperationWithBlock:^{NSLog(@"%@ with no %d",[NSThread currentThread],i);}];}

执行结果如下,可见与上面的描述相同。

2015-02-17 11:04:08.421 NSOpertaion[919:32337] <NSThread: 0x7bf91f50>{number = 9, name = (null)} with no 6
2015-02-17 11:04:08.421 NSOpertaion[919:32331] <NSThread: 0x7bf91c10>{number = 4, name = (null)} with no 1
2015-02-17 11:04:08.421 NSOpertaion[919:32338] <NSThread: 0x7bf915c0>{number = 6, name = (null)} with no 5
2015-02-17 11:04:08.421 NSOpertaion[919:32336] <NSThread: 0x7dab62c0>{number = 7, name = (null)} with no 4
2015-02-17 11:04:08.421 NSOpertaion[919:32339] <NSThread: 0x7dab61b0>{number = 3, name = (null)} with no 7
2015-02-17 11:04:08.421 NSOpertaion[919:32330] <NSThread: 0x7dab6110>{number = 2, name = (null)} with no 0
2015-02-17 11:04:08.421 NSOpertaion[919:32341] <NSThread: 0x7d97b3f0>{number = 5, name = (null)} with no 8
2015-02-17 11:04:08.421 NSOpertaion[919:32328] <NSThread: 0x7be6d450>{number = 10, name = (null)} with no 3
2015-02-17 11:04:08.421 NSOpertaion[919:32329] <NSThread: 0x7dab6450>{number = 8, name = (null)} with no 2
2015-02-17 11:04:08.448 NSOpertaion[919:32281] <NSThread: 0x7d96f040>{number = 1, name = main} with no 0
2015-02-17 11:04:08.449 NSOpertaion[919:32281] <NSThread: 0x7d96f040>{number = 1, name = main} with no 1
2015-02-17 11:04:08.449 NSOpertaion[919:32281] <NSThread: 0x7d96f040>{number = 1, name = main} with no 2
2015-02-17 11:04:08.449 NSOpertaion[919:32281] <NSThread: 0x7d96f040>{number = 1, name = main} with no 3
2015-02-17 11:04:08.450 NSOpertaion[919:32281] <NSThread: 0x7d96f040>{number = 1, name = main} with no 4
2015-02-17 11:04:08.450 NSOpertaion[919:32281] <NSThread: 0x7d96f040>{number = 1, name = main} with no 5
2015-02-17 11:04:08.450 NSOpertaion[919:32281] <NSThread: 0x7d96f040>{number = 1, name = main} with no 6
2015-02-17 11:04:08.450 NSOpertaion[919:32281] <NSThread: 0x7d96f040>{number = 1, name = main} with no 7
2015-02-17 11:04:08.450 NSOpertaion[919:32281] <NSThread: 0x7d96f040>{number = 1, name = main} with no 8

【自定义队列顺序执行】

使用NSBlockOperation对象的addDependency设置依赖关系,只有依赖的对象执行完毕后,自己才能执行。

例如下面的例子,三个任务要顺序执行,先下载,再处理,最后显示,通过这样的设定可以保证顺序:

- (void)SerialOperation{NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"下载");}];NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"处理");}];NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"显示");}];[op2 addDependency:op1];[op3 addDependency:op2];[self.myqueue addOperation:op1];[self.myqueue addOperation:op2];[self.myqueue addOperation:op3];}

注意这个执行和串行队列的异步任务不同点是,串行队列的异步任务仅仅开一个线程;自定义队列的顺序执行可能开辟多个但不会太多个线程。

注意上面的代码有一定的问题,因为显示只有主线程可以处理,所以op3应该放入主线程。

Tip:依赖关系可以跨队列,因此op3依赖op2在主线程中仍然有效,只需要修改op3的入队代码为:

[[NSOperationQueue mainQueue] addOperation:op3];

Tip:注意避开循环依赖,程序会崩溃。

【设定多线程的最大开销】

设定同时执行的最大线程数:通过队列的setMaxConcurrentOperationCount方法来设定,例如:

[self.myqueue setMaxConcurrentOperationCount:3];

应用场景:网络通信,例如3G开3个子线程,WIFI开6个子线程。

Tip:线程的开销主要是CPU和内存,还会耗电,因此应该考虑软件的能耗。

Tip:AFNetworing的底层是使用GCD开发的,接口是NSOperation。

转载于:https://www.cnblogs.com/aiwz/p/6154194.html

(五十六)iOS多线程之NSOperation相关推荐

  1. OpenCV学习笔记(五十六)——InputArray和OutputArray的那些事core OpenCV学习笔记(五十七)——在同一窗口显示多幅图片 OpenCV学习笔记(五十八)——读《Mast

    OpenCV学习笔记(五十六)--InputArray和OutputArray的那些事core 看过OpenCV源代码的朋友,肯定都知道很多函数的接口都是InputArray或者OutputArray ...

  2. iOS多线程之GCD小记

    iOS多线程之GCD小记 iOS多线程方案简介 从各种资料中了解到,iOS中目前有4套多线程的方案,分别是下列4中: 1.Pthreads 这是一套可以在很多操作系统上通用的多线程API,是基于C语言 ...

  3. 合肥工业大学机器人技术五十六题

    合肥工业大学机器人技术五十六题 题目要求 //拿球后行为,利用已有 Worldmodel(21) (1)在 playOn 模式下,拿到球以后朝前方快速带球. (2)在 PlayOn 模式下,拿到球以后 ...

  4. 中国五十六个民族简介

    56个民族是中华人民共和国灿烂星空中(五十六个星座). 中华民族共包括56个民族,汉族是中国的主体民族,占全部人口的91.51%,其他还有55个民族,占8.49%(第六次人口普查).汉族和55个少数民 ...

  5. 【正点原子FPGA连载】第五十六章 双目OV5640摄像头HDMI显示实验 -摘自【正点原子】新起点之FPGA开发指南_V2.1

    1)实验平台:正点原子新起点V2开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=609758951113 3)全套实验源码+手册+视频下载地址:ht ...

  6. Python编程基础:第五十六节 filter函数Filter

    第五十六节 filter函数Filter 前言 实践 前言 filter函数的作用是对可迭代对象内部的元素按照特定条件进行过滤,其书写方式为filter(function, iterable),第一个 ...

  7. JavaScript学习(五十六)—寄生式继承(临时构造器的使用)

    JavaScript学习(五十六)-寄生式继承(临时构造器的使用) 寄生式继承(临时构造器的使用): 之所以要使用临时构造器就是要在实现原型链继承时获取上级构造方法原型中的内容,而不要它的私有属性 默 ...

  8. MFC Windows 程序设计[五十六]之开启子对话框(附源码)

    MFC Windows 程序设计[五十六]之开启子对话框 程序之美 前言 主体 运行效果 核心代码 逻辑分析 结束语 程序之美 前言 MFC是微软公司提供的一个类库(class libraries), ...

  9. 达芬奇密码 第五十五章 第五十六章

    达芬奇密码 第五十五章 第五十六章[@more@] 第五十五章 索菲靠着兰登坐在长沙发上,喝着茶吃着烤饼,享受着食物的美味.雷·提彬爵士微笑着,在炉火前面笨拙地踱来踱去.假肢敲在地面上,发出" ...

最新文章

  1. 【iOS XMPP】使用XMPPFramewok(三):好友状态
  2. 软件测试b s环境如何配置,B/S架构测试环境搭建_DB2篇(Win32系统)
  3. 关于Nginx的配置文件解析
  4. OAuth2.0资源服务器之校验Token配置
  5. 大文件数据导出(后台执行,自动生成)
  6. 添加组件_苹果ios14怎么添加删除小组件 小组件叠放添加设置教程
  7. MATLAB通信系统建模与仿真
  8. 自己整理的90分以上最新物联网技术导论期末选择填空大题总考点
  9. Anaconda下载太慢问题解决
  10. flink 部署模式和运行时架构(会话模式、单作业模式、应用模式,JobManager、TaskManager,YARN 模式部署以及运行时架构)
  11. 最新 IOS应用开发Icon规格自动裁剪器(C#)
  12. python求积分面积的几个方法
  13. 程序猿段子_程序员段子
  14. 万字长文!推荐一款日志切割神器
  15. 喜报 | 强强联手,这件大事终于有着落了
  16. 如何使用格式工厂截取音乐或视频的片断
  17. 07.图6 旅游规划 [Dijkstra 算法]
  18. 威力曲面sw2020_威力曲面插件(SolidWorks曲面设计助手)V6.1 正式版
  19. SQL Server中已满事务日志原因的检测
  20. AD学习笔记(四)PCB布局分析

热门文章

  1. Mac OS X 10.10如何打开虚拟内存
  2. 基本算法研究1-冒泡排序算法测试
  3. UVA10236 斐波那契素数
  4. mysql 列 随机数_mysql mmp 某字段插入随机数!(说不定那天就忘记了,存下来再说)...
  5. 如何在vs2010中修改栈的大小
  6. oracle 整个表空间迁移,oracle11g迁移表空间
  7. Matlab数据标准化
  8. java 中的override overload 比较
  9. PHP培训选云和数据,送给云和数据郑州分中心PHP培训班全体学员的祝福
  10. 阿里云应用实战-IoT工业数据上云优化实践