多线程 (五)NSOperation
NSOperation是对GCD的分装,OC语言,更简单方便
NSOperation和NSOperationQueue一起使用也能实现多线程编程
基本步骤:
- 将操作封装到一个NSOperation对象中
- 将NSOperation对象添加到NSOperationQueue队列
- 系统会将NSOperationQueue中的NSOperation取出
- 将取出的NSOperation封装的操作放到一条新线程中执行
NSOperation是一个抽象类,不具备操作能力,必须使用它的子类:
- NSInvocationOperation
- NSBlockOperation(使用的最多)
- 自定义子类继承于NSOperation,实现相应的方法(使用较少)
1.NSInvocationOperation:
- (void)InvocationOperation
{
//创建队列,通过alloc init方式创建的队列是并发队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
for(int i = 0; i < 5; i++)
{
//创建操作
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(test) object:nil];
//把操作放到队列中
[queue addOperation:op];
}
} - (void)test
{
NSLog(@"当前线程 = %@",[NSThread currentThread]);
}
打印可以验证queue是一个并发队列

2.NSBlockOperation
- (void)BlockOperation
{
//创建队列,通过alloc init方式创建的队列是并发队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; for(int i = 0; i < 5; i++)
{
//创建操作
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"当前线程 = %@",[NSThread currentThread]);
}];
//把操作放到队列中
[queue addOperation:op];
}
}
也可以这样使用(更简单)
- (void)BlockOperationEasy
{
//创建队列,通过alloc init方式创建的队列是并发队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
NSLog(@"当前线程 = %@",[NSThread currentThread]);
}];
}
添加一个额外的操作
- (void)BlockOperation
{
//创建队列,通过alloc init方式创建的队列是并发队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//创建操作
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"当前线程 = %@",[NSThread currentThread]);
}];
//再添加一个操作
[op addExecutionBlock:^{
NSLog(@"这是一个额外的操作,线程 = %@",[NSThread currentThread]);
}];
//把操作放到队列中
[queue addOperation:op]; }
NSOperationQueue:
NSOperationQueue没有串行队列,但是它可以获取主队列,通过下面代码获取到主队列,添加到主队列中的任务都会在主线程中执行
[NSOperationQueue mainQueue]
线程间通讯 :
- (void)refreshUI
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
NSLog(@"多线程中执行的操作%@",[NSThread currentThread]);
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@"回到主线程更新UI%@",[NSThread currentThread]);
}];
}];
}
最大并发数:
- 并发数是指同时执行任务的数量
- 比如同时开启3个线程执行3个任务,并发数就是3
- NSOperation可以通过最大并发数控制同一时间执行操作数量
- (void)max
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 2;
for (int i = 0; i< 10; i++)
{
[queue addOperationWithBlock:^{
NSLog(@"i = %d, thread = %@",i,[NSThread currentThread]);
}];
}
}
结果出现了2,3,4,5四个线程,这是因为最大并发决定的是同一时间执行操作数量,而不是线程的数量;

挂起队列:
- 挂机队列是把任务保存在当前状态,之后可以继续
- 挂起操作不会影响已经在执行的任务
- (void)suspended
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
for (int i = 0; i< 10; i++)
{
if (i == 5)
{
//挂起队列
queue.suspended = YES;
//延迟2s
[NSThread sleepForTimeInterval:2];
//继续
queue.suspended = NO;
}
[queue addOperationWithBlock:^{ NSLog(@"i = %d, thread = %@",i,[NSThread currentThread]);
}];
}
}
取消操作
- 取消操作并不会影响队列的挂起状态
- (如果队列是挂起状态)一般取消操作后会把队列置于不挂起状态,便于后续操作
- 挂起队列,队列中的任务还存在,可以继续;取消操作,队列中的任务就没有了,只能重新添加任务
- (void)cancel
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//设置最大并发数为1
queue.maxConcurrentOperationCount = 1;
for (int i = 0; i< 10; i++)
{
[queue addOperationWithBlock:^{
[NSThread sleepForTimeInterval:1];
NSLog(@"i = %d, thread = %@",i,[NSThread currentThread]);
}];
}
//3S后取消队列里的所有操作
[NSThread sleepForTimeInterval:3];
[queue cancelAllOperations];
}
打印结果可以看出后面的操作都已经被取消了

依赖关系 :
- 依赖关系可以跨队列
- 注意不要循环依赖
- (void)dependecy
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation *one = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下载音乐");
}];
NSBlockOperation *two = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"打开音乐");
}];
NSBlockOperation *three = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"播放音乐");
}];
//添加任务依赖关系
[two addDependency:one];
[three addDependency:two]; //等待任务完成继续下一个任务,类似于GCD里的调度组
[queue addOperations:@[one,two,three] waitUntilFinished:YES];
NSLog(@"听完音乐放松一下");
}
多线程 (五)NSOperation的更多相关文章
- 多线程下NSOperation、NSBlockOperation、NSInvocationOperation、NSOperationQueue的使用
本篇文章主要介绍下多线程下NSOperation.NSBlockOperation.NSInvocationOperation.NSOperationQueue的使用,列举几个简单的例子. 默认情况下 ...
- iOS开发——多线程篇——NSOperation(基于GCD多线程编程),下载图片并合成新图片
一.NSOperation的基本概念1.简介NSOperation的作用配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperatio ...
- iOS开发多线程篇—NSOperation简单介绍
iOS开发多线程篇—NSOperation简单介绍 一.NSOperation简介 1.简单说明 NSOperation的作⽤:配合使用NSOperation和NSOperationQueue也能实现 ...
- iOS开发多线程篇—NSOperation基本操作
iOS开发多线程篇—NSOperation基本操作 一.并发数 (1)并发数:同时执⾏行的任务数.比如,同时开3个线程执行3个任务,并发数就是3 (2)最大并发数:同一时间最多只能执行的任务的个数. ...
- 多线程(五) java的线程锁
在多线程中,每个线程的执行顺序,是无法预测不可控制的,那么在对数据进行读写的时候便存在由于读写顺序多乱而造成数据混乱错误的可能性.那么如何控制,每个线程对于数据的读写顺序呢?这里就涉及到线程锁. 什么 ...
- {python--GIL锁}一 介绍 二 GIL介绍 三 GIL与Lock 四 GIL与多线程 五 多线程性能测试
python--GIL锁 GIL锁 本节目录 一 介绍 二 GIL介绍 三 GIL与Lock 四 GIL与多线程 五 多线程性能测试 一 背景知识 ''' 定义: In CPython, the gl ...
- 【iOS开发】多线程下NSOperation、NSBlockOperation、NSInvocationOperation、NSOperationQueue的使用
http://blog.csdn.net/crycheng/article/details/21799611 本篇文章主要介绍下多线程下NSOperation.NSBlockOperation.NSI ...
- IOS多线程(NSOperation,NSOperationQueue)
含义:NSOperation,NSOperationQueue是什么. The NSOperation class is an abstract class you use to encapsulat ...
- iOS开发多线程--(NSOperation/Queue)
iOS实现多线程的方式有三种,分别是NSThread.NSOperation.GCD. 关于GCD,请阅读GCD深入浅出学习 简介 NSOperation封装了需要执行的操作和执行操作所需的数据,提供 ...
- Java多线程(五) Lock接口,ReentranctLock,ReentrantReadWriteLock
在JDK5里面,提供了一个Lock接口.该接口通过底层框架的形式为设计更面向对象.可更加细粒度控制线程代码.更灵活控制线程通信提供了基础.实现Lock接口且使用得比较多的是可重入锁(Reentrant ...
随机推荐
- Swift标识符和关键字
任何一种计算机语言都离不开标识符和关键字,下面我们将详细介绍Swift标识符和关键字. 标示符 标识符就是给变量.常量.方法.函数.枚举.结构体.类.协议等指定的名字.构成标识符的字母均有一定的规范, ...
- (转)卸载和安装LINUX上的JDK
卸载默认的: 用root用户登陆到系统,打开一个终端输入 # rpm -qa|grep gcj 显示内容其中包含下面两行信息 # java-1.4.2-gcj-compat-1.4.2.0-27jpp ...
- css Hack 以及css的一些兼容问题小结
坚持每天做总结.今天下班还算早.写个跟css兼容有关的知识点.便于后期查看与学习.一.先说说各种主流浏览器的内核 浏览器最重要或者说核心的部分是“Rendering Engine”,可大概译为“渲染引 ...
- Linux 配置文件
Linux系统的配置文件,在多用户.多任务环境中,配置文件控制用户权限.系统应用程序.守护进程.服务和其他管理任务.这些任务包括管理用户账号.分配磁盘配额.管理电子邮件和新闻组,以及配置内核参数.以下 ...
- node.js:怎样同时执行多条SQLs,且只有一个回调
本文主要介绍开源node.js库mysql-queries,其可以同时执行多条SQLs,且只有一个回调.同时抛砖引玉,与大家交流node.js开发经验. node.js很大的特点就是事件驱动.非阻塞和 ...
- Asp.net 引用css/js资源文件
注意Page.ResolveUrl之前的双引号,不是单引号 <script type="text/javascript" src="<%= Page.Reso ...
- GridView - javascript 触发后台 OnSelectedIndexChanged
1.ASPX <asp:GridView ID="gdvDealers" runat="server" AutoGenerateColumns=" ...
- AngularJS(10)-数据验证
AngularJS 表单和控件可以提供验证功能,并对用户输入的非法数据进行警告.客户端的验证不能确保用户输入数据的安全,所以服务端的数据验证也是必须的. <!DOCTYPE html> & ...
- Python入门二:函数
一.函数的定义和使用 1.基本结构: def 函数名(参数): """ 文档字符串 """ 函数体 返回值 2.函数名: 和变量名命名规则一 ...
- UI事件监听的击穿
什么是UI事件监听的击穿 在游戏视图中,有两个UI界面叠在一起的时候,单击一个空白处,却触发了被覆盖在下层了UI界面中的单击事件,这就是单击击穿了上层界面. 假设场景中放置了一个箱子,单击箱子会触发一 ...