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. Cocos开发中Visual Studio下libcurl库开发环境设置

    我们介绍一下win32中Visual Studio下libcurl库开发环境设置.Cocos2d-x引擎其实已经带有为Win32下访问libcurl库,Cocos2d-x 3.x中libcurl库文件 ...

  2. select2 取值 赋值

    项目中心引入了select2的插件.优势:可以多选.搜索,缺点:存取值不如select方便. select2 取值: <script type="text/javascript&quo ...

  3. 学习 .net 的一些主要网站

    学习 .net 的一些主要网站 来自 http://www.cnblogs.com/trymybest121/articles/500176.html   http://msdn.microsoft. ...

  4. jCallout 实现气泡提示

    在提交表单前.焦点转移后或者 keyup 时往往需要对输入的文本就行检验,如果输入内容不符合相关约定则要进行提示或警告,有一个叫 jCallout 的插件可以轻松实现该功能,该插件基于  jQuery ...

  5. vs2010创建COM以及调用

    1,创建COM组件 2,调用COM 3,MFC调用COM

  6. gitignre

    1.配置语法: 以斜杠“/”开头表示目录: 以星号“*”通配多个字符: 以问号“?”通配单个字符 以方括号“[]”包含单个字符的匹配列表: 以叹号“!”表示不忽略(跟踪)匹配到的文件或目录: PLAC ...

  7. pthread 实现生产者消费者问题

    经典的生产者消费者问题,在这里用信号量和互斥量来实现生产和消费者模型   #include<cstdlib> #include<cstdio> #include<unis ...

  8. javascript之数据推送

    我们使用ajax与后台服务进行交互,常常是通过触发事件来单次交互,但对于有些web应用来说,需要前台与后台保持长连接,前端不定时地接收后台推送的数据信息, 例如:股票行情分析.聊天室和网页在线游戏等. ...

  9. swing画太极图案源码

    package org.open.swing.taiji; /** * @(#)Taichi.java * * * @author * @version 1.00 2007/6/12 */ impor ...

  10. OWIN OAuth 2.0 Authorization Server

    http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server The assumption ...