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. 基于KNN的发票识别

    项目概况: 有一个PDF文件,里面的每页都是一张发票,把每页的发票单独存为一个PDF并用该发票的的发票号码进行文件的命名,发票号码需要OCR识别,即识别下图中红色方块的内容. 一:拆分PDF 现有一个 ...

  2. Transformers 词汇表 | 二

    作者|huggingface 编译|VK 来源|Github 词汇表每种模型都不同,但与其他模型相似.因此,大多数模型使用相同的输入,此处将在用法示例中进行详细说明. 输入ID 输入id通常是传递给模 ...

  3. Android | 教你如何用华为HMS MLKit SDK 三十分钟在安卓上开发一个微笑抓拍神器

    Android | 只要三十分钟就可以在手机上开发一个微笑抓拍神器!!! 前言 前段时间Richard Yu在发布会上给大家介绍了华为HMS Core4.0,回顾发布会信息请戳: 华为面向全球发布HM ...

  4. Java并发基础10:原子性操作类的使用

    在 java5 以后,我们接触到了线程原子性操作,也就是在修改时我们只需要保证它的那个瞬间是安全的即可,经过相应的包装后可以再处理对象的并发修改,本文总结一下Atomic系列的类的使用方法,其中包含: ...

  5. c语言 0与非0

    ------------恢复内容开始------------ 结论: 其它的编程语言中有布尔数据类型,并用百来表示逻辑真和逻辑假,C语言没有这个内置类度型,在C语言中真和假是用整型值来表示知的,0就表 ...

  6. java 第六周课后作业

    1.定义长度位5的整型数组,输入他们的值,用冒泡排序后输出. Scanner sc = new Scanner(System.in); int[] arr = new int[5]; for (int ...

  7. LeetCode 题解 | 面试题57 - II. 和为s的连续正数序列

    题目描述 面试题57 - II. 和为s的连续正数序列 难度简单37收藏分享切换为英文关注反馈 输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数). 序列内 ...

  8. find的基本查询命令《一》

    一. find的基本查询命令 find命令最常用的是查找某个文件,如: find ./ -name "abc.txt" 则会在当前目录及子目录下查找abc.txt文件 更常用的是查 ...

  9. 基于 HTML5 WebGL 的 水泥工厂可视化系统

    前言 如今的制造行业,基于数据进行生产策略制定与管理已经成为一种趋势,特别是 工业4.0 的浪潮下,数据战略已经成为很多制造企业的优先战略,而数据可视化以更直观的方式,帮助指导决策,成为数据分析传递信 ...

  10. SpringCloud(三)之我学 Hystrix

    1.断路器 在消费服务的启动类,添加注解:@EnableCircuitBreaker,在消费服务的调用类上,添加注解:@HystrixCommand(fallbackMethod = "&q ...