NSOperation是对GCD的分装,OC语言,更简单方便

NSOperation和NSOperationQueue一起使用也能实现多线程编程

基本步骤:

  1. 将操作封装到一个NSOperation对象中
  2. 将NSOperation对象添加到NSOperationQueue队列
  3. 系统会将NSOperationQueue中的NSOperation取出
  4. 将取出的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的更多相关文章

  1. 多线程下NSOperation、NSBlockOperation、NSInvocationOperation、NSOperationQueue的使用

    本篇文章主要介绍下多线程下NSOperation.NSBlockOperation.NSInvocationOperation.NSOperationQueue的使用,列举几个简单的例子. 默认情况下 ...

  2. iOS开发——多线程篇——NSOperation(基于GCD多线程编程),下载图片并合成新图片

    一.NSOperation的基本概念1.简介NSOperation的作用配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperatio ...

  3. iOS开发多线程篇—NSOperation简单介绍

    iOS开发多线程篇—NSOperation简单介绍 一.NSOperation简介 1.简单说明 NSOperation的作⽤:配合使用NSOperation和NSOperationQueue也能实现 ...

  4. iOS开发多线程篇—NSOperation基本操作

    iOS开发多线程篇—NSOperation基本操作 一.并发数 (1)并发数:同时执⾏行的任务数.比如,同时开3个线程执行3个任务,并发数就是3 (2)最大并发数:同一时间最多只能执行的任务的个数. ...

  5. 多线程(五) java的线程锁

    在多线程中,每个线程的执行顺序,是无法预测不可控制的,那么在对数据进行读写的时候便存在由于读写顺序多乱而造成数据混乱错误的可能性.那么如何控制,每个线程对于数据的读写顺序呢?这里就涉及到线程锁. 什么 ...

  6. {python--GIL锁}一 介绍 二 GIL介绍 三 GIL与Lock 四 GIL与多线程 五 多线程性能测试

    python--GIL锁 GIL锁 本节目录 一 介绍 二 GIL介绍 三 GIL与Lock 四 GIL与多线程 五 多线程性能测试 一 背景知识 ''' 定义: In CPython, the gl ...

  7. 【iOS开发】多线程下NSOperation、NSBlockOperation、NSInvocationOperation、NSOperationQueue的使用

    http://blog.csdn.net/crycheng/article/details/21799611 本篇文章主要介绍下多线程下NSOperation.NSBlockOperation.NSI ...

  8. IOS多线程(NSOperation,NSOperationQueue)

    含义:NSOperation,NSOperationQueue是什么. The NSOperation class is an abstract class you use to encapsulat ...

  9. iOS开发多线程--(NSOperation/Queue)

    iOS实现多线程的方式有三种,分别是NSThread.NSOperation.GCD. 关于GCD,请阅读GCD深入浅出学习 简介 NSOperation封装了需要执行的操作和执行操作所需的数据,提供 ...

  10. Java多线程(五) Lock接口,ReentranctLock,ReentrantReadWriteLock

    在JDK5里面,提供了一个Lock接口.该接口通过底层框架的形式为设计更面向对象.可更加细粒度控制线程代码.更灵活控制线程通信提供了基础.实现Lock接口且使用得比较多的是可重入锁(Reentrant ...

随机推荐

  1. UML建模文章总结

    一.为什么要学习UML UML是Unified Modeling Language(统一建模语言)的简称.UML是对软件密集型系统中的制品进行可视化.详述.构造和文档化的语言.制品{Artifact} ...

  2. LXC-Linux Containers介绍

    Linux Containers,Linux的容器,容器嘛,可以想象成一个大的装东西的罐子,罐子口很大,里面可以装很多同样形状,只不过大小不同的小罐子.专业的话,叫做基于容器的操作系统层面的虚拟化技术 ...

  3. MySQL EER反向建表

    Database > Synchronize Model... Choose Stored Connection Select the Schemata Choose which to upda ...

  4. 修改zepto源代码,使支持wp8的ie10

    注意:当前1.1.3版本的zepto,已经有模块来支持wp8 原先的zepto,通过__proto__赋值,来使dom继承到$.fn方法, 无奈IE11之前的IE10,IE9不支持这种写法, 所以我们 ...

  5. window.print打印指定div实例代码

    window.print可以打印网页,但有时候我们只希望打印特定控件或内容,怎么办呢,请看下面的例子 首先我们可以把要打印的内容放在div中,然后用下面的代码进行打印. 复制代码代码如下: <h ...

  6. PHP中CURL技术模拟登陆抓取网站信息,用与微信公众平台成绩查询

    伴随微信的红火,微信公众平台成为许多开发者的下一个目标.笔者本身对于这种新鲜事物没有如此多的吸引力.但是最近有朋友帮忙开发微信公众平台中一个成绩查询的功能.于是便在空余时间研究了一番. 主要的实现步骤 ...

  7. what is WLAN ? when and why we need use it ?

    无线局域网络(Wireless Local Area Networks: WLAN)是相当便利的数据传输系统,它利用射频(Radio Frequency: RF)的技术,取代旧式碍手碍脚的双绞铜线(C ...

  8. linux乱码问题:LANG变量的秘诀

    对于国内的Linux用户,经常烦恼的一个问题是:系统常常在需要显示中文的时候却显示成了乱码,而由于某些原因,需要英文界面的系统的时候,却苦于系统不能正常输入和显示中文.另外,由于大部分主要Linux发 ...

  9. flex直接访问服务器

    1.读取指定文件里的xml: <?xml version="1.0" encoding="utf-8"?><s:WindowedApplica ...

  10. (转)MVC 3 数据验证 Model Validation 详解

    继续我们前面所说的知识点进行下一个知识点的分析,这一次我们来说明一下数据验证.其实这是个很容易理解并掌握的地方,但是这会浪费大家狠多的时间,所以我来总结整理一下,节约一下大家宝贵的时间. 在MVC 3 ...