AJ分享,必须精品

一:队列的类型与队列添加任务

1: 主队列

  • [NSOperationQueue mainQueue]
  • 添加到”主队列”中的操作,都会放到主线程中执行。

2:非主队列

  • [[NSOperationQueue alloc] init]
  • 添加到”非主队列”中的操作,都会放到子线程中执行。

3:队列添加任务

    • (void)addOperation:(NSOperation *)op;
    • (void)addOperationWithBlock:(void (^)(void))block;

二:常见用法

1: 设置最大并发数

(1)并发数:同时执⾏行的任务数.比如,同时开3个线程执行3个任务,并发数就是3。
(2)最大并发数:同一时间最多只能执行的任务的个数。
(3)最⼤大并发数的相关⽅方法。
- (NSInteger)maxConcurrentOperationCount;
- (void)setMaxConcurrentOperationCount:(NSInteger)cnt;
说明:如果没有设置最大并发数,那么并发的个数是由系统内存和CPU决定的,可能内存多久开多一点,内存少就开少一点。
注意:num的值并不代表线程的个数,仅仅代表线程的ID。
提示:最大并发数不要乱写(5以内),不要开太多,一般以2~3为宜,因为虽然任务是在子线程进行处理的,但是cpu处理这些过多的子线程可能会影响UI,让UI变卡。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// 1.创建一个队列(非主队列)
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 2.设置最大并发(最多同时并发执行2个任务)
queue.maxConcurrentOperationCount = 2; // 3.添加操作到队列中(自动异步执行任务,并发)
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下载图片1---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下载图片2---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下载图片3---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下载图片4---%@", [NSThread currentThread]);
}];
NSInvocationOperation *operation5 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil]; [queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
[queue addOperation:operation4];
[queue addOperation:operation5];
[queue addOperationWithBlock:^{
NSLog(@"下载图片5---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"下载图片6---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"下载图片7---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"下载图片8---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"下载图片9---%@", [NSThread currentThread]);
}];
}

效果:我们设置了9个模拟下载的操作,同一时间开启的线程最多为两个,注意,途中有2,3,4 三条线程,但是我们保证了再同一时间只有两条线程,2开始做事,后来不做了,就换线程3,4了。

2: 队列的其他操作

  • 取消所有的操作
  • (void)cancelAllOperations;
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// 1.创建一个队列(非主队列)
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // // 2.设置最大并发(最多同时并发执行2个任务)
// queue.maxConcurrentOperationCount = 2; // 3.添加操作到队列中(自动异步执行任务,并发)
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下载图片1---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下载图片2---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下载图片3---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下载图片4---%@", [NSThread currentThread]);
}];
NSInvocationOperation *operation5 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil]; [queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
[queue addOperation:operation4];
[queue addOperation:operation5];
[queue addOperationWithBlock:^{
NSLog(@"下载图片5---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"下载图片6---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"下载图片7---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"下载图片8---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"下载图片9---%@", [NSThread currentThread]);
}]; [queue cancelAllOperations];
}

结果图:

这个的用法其实是在管理内存时候用的

应该这么用

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning]; [queue cancelAllOperations]; // 取消队列中的所有任务(不可恢复)
}

  • 暂停所有的操作
    [queue setSuspended:YES];

  • 恢复所有的操作
    [queue setSuspended:NO];

跟取消所有操作差不多,实际情况中这样用,当我们的tableview跟客户交互的时候(滚动)暂停,不交互了继续执行

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
// [queue setSuspended:YES]; // 暂停队列中的所有任务
} - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
// [queue setSuspended:NO]; // 恢复队列中的所有任务
}

三:操作之间的依赖(面试题)

  • NSOperation之间可以设置依赖来保证执行顺序
  • [operationB addDependency:operationA];
    // 操作B依赖于操作A,等操作A执行完毕后,才会执行操作B
  • 注意:不能相互依赖,比如A依赖B,B依赖A
  • 可以在不同queue的NSOperation之间创建依赖关系

简单来说就是让线程执行有顺序,是一个执行依赖于另一个线程的执行。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
/**
假设有A、B、C三个操作,要求:
1. 3个操作都异步执行
2. 操作C依赖于操作B
3. 操作B依赖于操作A
*/ // 1.创建一个队列(非主队列)
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 2.创建3个操作
NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"A---%@", [NSThread currentThread]);
}]; NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"B---%@", [NSThread currentThread]);
}];
NSBlockOperation *operationC = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"C---%@", [NSThread currentThread]);
}]; // 设置依赖
[operationB addDependency:operationA];
[operationC addDependency:operationB]; // 3.添加操作到队列中(自动异步执行任务)
[queue addOperation:operationC];
[queue addOperation:operationA];
[queue addOperation:operationB]; }

效果

四:线程之间的通信

NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
// 1.执行一些比较耗时的操作的代码 [[NSOperationQueue mainQueue] addOperationWithBlock:^{
// 2.回到主线程操作的代码
}];
}];

这个回看前面下载图片类似的案例就可以了。就是在子线程执行了然后会回主线程进行操作。

AJ学IOS(54)多线程网络之NSOperation重要知识的更多相关文章

  1. iOS开发多线程篇—自定义NSOperation

    iOS开发多线程篇—自定义NSOperation 一.实现一个简单的tableView显示效果 实现效果展示: 代码示例(使用以前在主控制器中进行业务处理的方式) 1.新建一个项目,让控制器继承自UI ...

  2. AJ学IOS(53)多线程网络之NSOperation简介

    AJ分享,必须精品 一:简单介绍 1:NSOperation的作⽤使用步骤: 配合使用NSOperation和NSOperationQueue也能实现多线程编程. NSOperation和NSOper ...

  3. AJ学IOS(48)多线程网络之多线程简单了解

    AJ分享,必须精品 一:进程和线程 1:什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内. 比如同时打开QQ.Xcode,系统就会分 ...

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

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

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

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

  6. AJ学IOS 之微博项目实战(2)微博主框架-自定义导航控制器NavigationController

    AJ分享,必须精品 一:添加导航控制器 上一篇博客完成了对底部的TabBar的设置,这一章我们完成自定义导航控制器(NYNavigationController). 为啥要做自定义呢,因为为了更好地封 ...

  7. AJ学IOS(13)UI之UITableView学习(下)汽车名牌带右侧索引

    AJ分享,必须精品 先看效果图 代码 ViewController #import "NYViewController.h" #import "NYCarGroup.h& ...

  8. AJ学IOS(55)多线程网络之图片下载框架之SDWebImage

    AJ分享,必须精品 效果: 代码: - (NSArray *)apps { if (!_apps) { NSArray *dictArray = [NSArray arrayWithContentsO ...

  9. AJ学IOS(49)多线程网络之线程的创建NSThreand

    AJ分享,必须精品 一:NSThread的基本使用 1:创建和启动线程 一个NSThread对象就代表一条线程 创建.启动线程 NSThread *thread = [[NSThread alloc] ...

随机推荐

  1. 云CRM系统安全吗

    云CRM系统有一个特点只要连接互联网就能够进行访问,这种访问可以是移动端也可以是电脑端的,而且本地CRM系统只允许电脑端访问.云CRM系统将数据存储在云服务器上,很多人就会问云CRM系统安全吗?下面和 ...

  2. Java8 Stream流

    第三章 Stream流 <Java8 Stream编码实战>的代码全部在https://github.com/yu-linfeng/BlogRepositories/tree/master ...

  3. 手把手教大家如何用scrapy爬虫框架爬取王者荣耀官网英雄资料

    之前被两个关系很好的朋友拉入了王者荣耀的大坑,奈何技术太差,就想着做一个英雄的随查手册,这样就可以边打边查了.菜归菜,至少得说明咱打王者的态度是没得说的,对吧?大神不喜勿喷!!!感谢!!废话不多说,开 ...

  4. MyBatis框架——单表查询

    Mybatis单表查询,示例 1.创建数据库 /* Navicat MySQL Data Transfer Source Server : localhost Source Server Versio ...

  5. shell脚本基础-语法

    一 变量 [root@T_FOOT-Home2-ZZZ01 ~]# a=hello [root@T_FOOT-Home2-ZZZ01 ~]# echo $a hello [root@T_FOOT-Ho ...

  6. 1036. 跟奥巴马一起编程(15) Java版

    美国总统奥巴马不仅呼吁所有人都学习编程,甚至以身作则编写代码,成为美国历史上首位编写计算机代码的总统.2014年底,为庆祝"计算机科学教育周"正式启动,奥巴马编写了很简单的计算机代 ...

  7. test命令的使用以及判断语法

    test命令 Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值.字符和文件三个方面的测试. 语法:test EXPRESSION 或者 [ EXPRESSION ] 字符串判断( ...

  8. CSAPP-bomblab

    DO NOT READ THIS ARTICLE. I wrote bullshit in English. This lab I have finished once, so this articl ...

  9. arcgis发布服务后显示证书不安全,将https改为http

    arcgis server发布服务后显示证书不安全,无法浏览. 要通过https://localhost:port/arcgis/admin作如下修改 update之后地图服务会重启,耐心等待一会儿就 ...

  10. Feign客户端的重构,新建springcloud架构

    1,在上篇博文中,已经实现了feign 客户端来远程调用接口的功能,因为feign 客户端在springcloud 开发过程中是比较常用的方式 https://www.cnblogs.com/pick ...