NSOperation的高级功能——线程间通信&最大并发数&挂起&取消全部操作
2015-10-23 09:19
381 查看
线程间通信:就是在别的线程执行耗时操作,在主线程更新UI
NSOperationQueue *q = [[NSOperationQueue alloc] init];
[q addOperationWithBlock:^{
NSLog(@"耗时操作......%@", [NSThread currentThread]);
//
在主线程更新UI
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@"更新UI......%@", [NSThread currentThread]);
}];
}];
最大并发数:
什么是并发数?
同时执行的任务数。比如同时开启三个线程执行三个任务,并发数就是3.
最大并发数相关的方法:
-(NSInteger)maxConcurrentOperationCount;
-(void)setMaxConcurrentOperationCount:(NSInteger)cnt;
剖析最大并发数:并发数就是同时执行操作的数量,并不是只线程的个数。就是指同时执行任务的个数,当一个线程执行完毕后会有一个回收到线程池的过程,这时如果线程池中还有别的线程就会直接拿出来进行任务的执行。如果线程池中没有线程,就会等待回收后的线程。
队列的取消、暂停、和恢复
取消队列的所有操作
-(void)cancelAllOperations;
提示:也可以调用NSOperation的-(void)cancel方法取消单个操作。
暂停和恢复队列
-(void)setSuspended:(BOOL)b; // YES表示暂停队列 NO表示恢复队列
-(BOOL)isSuspend;
获取队列操作数:
operationCount(只读属性)
注意:
(1)暂停不会删除队列内的操作。只是把队列挂起。暂停和挂起都是针对队列而言的。暂停后还可以重新恢复接着原来的任务进行执行。
(2)取消全部任务的操作会清空队列里的所有任务。
(3)暂停和取消都是对队列里的操作而言的,而正在执行的操作是无法取消或暂停的。
在实际的开发中:通常定义一个全局的操作队列, 然后就可以把所有的任务都添加进去。在开发中需要注意的两点:
(1)在用户点击”暂停/继续”的按钮触发的事件中,需要先判断当前队列内是否有任务,如果全局队列内没有任务就直接return返回,从而没有任务的时候不会改变队列的挂起和恢复状态。
(2)在用户点击”取消全部操作”的按钮触发的事件中,取消操作之后需要重置全局队列为恢复状态,这样不管原先全局队列的状态如何,在取消全部操作之后又重新置于初始状态。从而不会影响新的操作。
新建工程,代码如下:
运行结果图如下:
NSOperationQueue *q = [[NSOperationQueue alloc] init];
[q addOperationWithBlock:^{
NSLog(@"耗时操作......%@", [NSThread currentThread]);
//
在主线程更新UI
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@"更新UI......%@", [NSThread currentThread]);
}];
}];
最大并发数:
什么是并发数?
同时执行的任务数。比如同时开启三个线程执行三个任务,并发数就是3.
最大并发数相关的方法:
-(NSInteger)maxConcurrentOperationCount;
-(void)setMaxConcurrentOperationCount:(NSInteger)cnt;
剖析最大并发数:并发数就是同时执行操作的数量,并不是只线程的个数。就是指同时执行任务的个数,当一个线程执行完毕后会有一个回收到线程池的过程,这时如果线程池中还有别的线程就会直接拿出来进行任务的执行。如果线程池中没有线程,就会等待回收后的线程。
队列的取消、暂停、和恢复
取消队列的所有操作
-(void)cancelAllOperations;
提示:也可以调用NSOperation的-(void)cancel方法取消单个操作。
暂停和恢复队列
-(void)setSuspended:(BOOL)b; // YES表示暂停队列 NO表示恢复队列
-(BOOL)isSuspend;
获取队列操作数:
operationCount(只读属性)
注意:
(1)暂停不会删除队列内的操作。只是把队列挂起。暂停和挂起都是针对队列而言的。暂停后还可以重新恢复接着原来的任务进行执行。
(2)取消全部任务的操作会清空队列里的所有任务。
(3)暂停和取消都是对队列里的操作而言的,而正在执行的操作是无法取消或暂停的。
在实际的开发中:通常定义一个全局的操作队列, 然后就可以把所有的任务都添加进去。在开发中需要注意的两点:
(1)在用户点击”暂停/继续”的按钮触发的事件中,需要先判断当前队列内是否有任务,如果全局队列内没有任务就直接return返回,从而没有任务的时候不会改变队列的挂起和恢复状态。
(2)在用户点击”取消全部操作”的按钮触发的事件中,取消操作之后需要重置全局队列为恢复状态,这样不管原先全局队列的状态如何,在取消全部操作之后又重新置于初始状态。从而不会影响新的操作。
新建工程,代码如下:
// // ViewController.m // NSOperation之线程间通信 // // Created by apple on 15/10/22. // Copyright (c) 2015年 LiuXun. All rights reserved. // #import "ViewController.h" @interface ViewController () /** 一般开发中,会定义一个全局的队列。整个程序都可以把操作往里面放。 负责调度所有的操作 */ @property(nonatomic, strong) NSOperationQueue *opQueue; @end @implementation ViewController /** 小结: 只要是NSOperation的子类,就能添加到操作队列 - 一旦操作添加到队列, 就会自动异步执行 - 如果没有添加到队列, 而是使用start方法,就会在当前线程执行操作 - 如果是线程间通信, 可以使用[NSOperaionQueue mainQueue] 拿到主队列,往主队列添加操作(更新UI) */ /** 懒加载的方式,初始化NSOperationQueue对象 */ -(NSOperationQueue *)opQueue { if(_opQueue == nil) { _opQueue = [[NSOperationQueue alloc] init]; } return _opQueue; } -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self opDemo2]; } #pragma mark - 线程间通信(非常重要) -(void)opDemo1 { NSOperationQueue *q = [[NSOperationQueue alloc] init]; [q addOperationWithBlock:^{ NSLog(@"耗时操作......%@", [NSThread currentThread]); // 在主线程更新UI [[NSOperationQueue mainQueue] addOperationWithBlock:^{ NSLog(@"更新UI......%@", [NSThread currentThread]); }]; }]; } #pragma mark- 最大并发数 /** 注意:最大并发数不是说线程的数量,而是说同时进行操作的数量 */ -(void)opDemo2 { self.opQueue.maxConcurrentOperationCount = 2; for(int i=0; i<10 ; i++){ NSOperation *op = [NSBlockOperation blockOperationWithBlock:^{ [NSThread sleepForTimeInterval:1.0]; NSLog(@"%@------%d", [NSThread currentThread], i); }]; [self.opQueue addOperation:op]; } } #pragma mark - 高级操作 挂起 // 就是暂停和继续: 对队列的操作 /** 应用场景:比如当我们在有WiFi的地发用手机下载电影,但是有事情走开了,断网了电影只下载了一半,这时就需要挂起,等到了有网的地方又可以接着原来的进度下载。 切记:挂起的是队列,不会影响已经在执行的操作 */ -(IBAction)pause { // 判断操作的数量,当前队列里面是否有操作 if(self.opQueue.operationCount == 0){ NSLog(@"没有操作"); return; // 没有操作的时候直接return,不会修改队列的状态 } // 暂停继续 : self.opQueue.suspended = !self.opQueue.suspended; if(self.opQueue.suspended){ NSLog(@"暂停"); }else { NSLog(@"继续"); } } #pragma mark- 高级操作 队列取消 /** 取消操作并不会影响队列的挂起状态 */ -(IBAction)cancel { // 取消队列内的所有操作 // 只是取消队列里的任务,而正在执行的任务是无法取消的 // 另外取消了任务就是删除了队列内的所有操作 [self.opQueue cancelAllOperations]; NSLog(@"取消所有操作"); // 取消队列的挂起状态(只要是取消了队列的操作,我们就把队列处于一个启动状态,以便于后续的开始) self.opQueue.suspended = NO; } @end界面图如下:
运行结果图如下:
相关文章推荐
- Hadoop--Hadoop核心之HDFS
- 在linux下挂载、卸载U盘
- 在Linux下安装JDK (ubuntu)
- Hadoop--Hadoop的伪分布式环境搭建
- 黄聪:如何添加360浏览器(chrome)添加JavaScript例外,禁止网站加载JS
- Hadoop--Linux环境搭建
- 在linux下配置静态IP
- Linux内核加载全流程
- Linux oops信息的分析
- datagrid报Cannot read property '' of null
- Linux-CenOS7 Samba的安装与配置
- 光流Optical Flow介绍与OpenCV实现
- Web API应用架构在Winform混合框架中的应用(3)--Winfrom界面调用WebAPI的过程分解
- Nginx设置Js、Css等静态文件的缓存过期时间
- linux硬件级虚拟机系统 电脑安桌游戏多开完全去除vm标识去虚拟化
- opencv2.4.11安装--配置
- Linux 磁盘管理
- Linux 文件与目录管理
- linux文件属性
- linux系统启动过程