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变卡。

  1. -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
  2. {
  3. // 1.创建一个队列(非主队列)
  4. NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  5. // 2.设置最大并发(最多同时并发执行2个任务)
  6. queue.maxConcurrentOperationCount = 2;
  7. // 3.添加操作到队列中(自动异步执行任务,并发)
  8. NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
  9. NSLog(@"下载图片1---%@", [NSThread currentThread]);
  10. }];
  11. NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
  12. NSLog(@"下载图片2---%@", [NSThread currentThread]);
  13. }];
  14. NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
  15. NSLog(@"下载图片3---%@", [NSThread currentThread]);
  16. }];
  17. NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{
  18. NSLog(@"下载图片4---%@", [NSThread currentThread]);
  19. }];
  20. NSInvocationOperation *operation5 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil];
  21. [queue addOperation:operation1];
  22. [queue addOperation:operation2];
  23. [queue addOperation:operation3];
  24. [queue addOperation:operation4];
  25. [queue addOperation:operation5];
  26. [queue addOperationWithBlock:^{
  27. NSLog(@"下载图片5---%@", [NSThread currentThread]);
  28. }];
  29. [queue addOperationWithBlock:^{
  30. NSLog(@"下载图片6---%@", [NSThread currentThread]);
  31. }];
  32. [queue addOperationWithBlock:^{
  33. NSLog(@"下载图片7---%@", [NSThread currentThread]);
  34. }];
  35. [queue addOperationWithBlock:^{
  36. NSLog(@"下载图片8---%@", [NSThread currentThread]);
  37. }];
  38. [queue addOperationWithBlock:^{
  39. NSLog(@"下载图片9---%@", [NSThread currentThread]);
  40. }];
  41. }

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

2: 队列的其他操作

  • 取消所有的操作
  • (void)cancelAllOperations;
  1. -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
  2. {
  3. // 1.创建一个队列(非主队列)
  4. NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  5. // // 2.设置最大并发(最多同时并发执行2个任务)
  6. // queue.maxConcurrentOperationCount = 2;
  7. // 3.添加操作到队列中(自动异步执行任务,并发)
  8. NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
  9. NSLog(@"下载图片1---%@", [NSThread currentThread]);
  10. }];
  11. NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
  12. NSLog(@"下载图片2---%@", [NSThread currentThread]);
  13. }];
  14. NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
  15. NSLog(@"下载图片3---%@", [NSThread currentThread]);
  16. }];
  17. NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{
  18. NSLog(@"下载图片4---%@", [NSThread currentThread]);
  19. }];
  20. NSInvocationOperation *operation5 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil];
  21. [queue addOperation:operation1];
  22. [queue addOperation:operation2];
  23. [queue addOperation:operation3];
  24. [queue addOperation:operation4];
  25. [queue addOperation:operation5];
  26. [queue addOperationWithBlock:^{
  27. NSLog(@"下载图片5---%@", [NSThread currentThread]);
  28. }];
  29. [queue addOperationWithBlock:^{
  30. NSLog(@"下载图片6---%@", [NSThread currentThread]);
  31. }];
  32. [queue addOperationWithBlock:^{
  33. NSLog(@"下载图片7---%@", [NSThread currentThread]);
  34. }];
  35. [queue addOperationWithBlock:^{
  36. NSLog(@"下载图片8---%@", [NSThread currentThread]);
  37. }];
  38. [queue addOperationWithBlock:^{
  39. NSLog(@"下载图片9---%@", [NSThread currentThread]);
  40. }];
  41. [queue cancelAllOperations];
  42. }

结果图:

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

应该这么用

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

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

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

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

  1. - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
  2. {
  3. // [queue setSuspended:YES]; // 暂停队列中的所有任务
  4. }
  5. - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
  6. {
  7. // [queue setSuspended:NO]; // 恢复队列中的所有任务
  8. }

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

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

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

  1. -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
  2. {
  3. /**
  4. 假设有A、B、C三个操作,要求:
  5. 1. 3个操作都异步执行
  6. 2. 操作C依赖于操作B
  7. 3. 操作B依赖于操作A
  8. */
  9. // 1.创建一个队列(非主队列)
  10. NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  11. // 2.创建3个操作
  12. NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{
  13. NSLog(@"A---%@", [NSThread currentThread]);
  14. }];
  15. NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{
  16. NSLog(@"B---%@", [NSThread currentThread]);
  17. }];
  18. NSBlockOperation *operationC = [NSBlockOperation blockOperationWithBlock:^{
  19. NSLog(@"C---%@", [NSThread currentThread]);
  20. }];
  21. // 设置依赖
  22. [operationB addDependency:operationA];
  23. [operationC addDependency:operationB];
  24. // 3.添加操作到队列中(自动异步执行任务)
  25. [queue addOperation:operationC];
  26. [queue addOperation:operationA];
  27. [queue addOperation:operationB];
  28. }

效果

四:线程之间的通信

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

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

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. 强连通分量SCC 2-SAT

    强连通分量SCC 2-SAT 部分资料来自: 1.https://blog.csdn.net/whereisherofrom/article/details/79417926 2.https://ba ...

  2. .Net微服务实战之技术选型篇

    王者荣耀 去年我有幸被老领导邀请以系统架构师的岗位带技术团队,并对公司项目以微服务进行了实施.无论是技术团队还是技术架构都是由我亲自的从0到1的选型与招聘成型的,此过程让我受益良多,因此也希望在接下来 ...

  3. VMWARE虚拟机安装系统提示CPU已被客户机操作系统禁用和secureCUT乱码

    错误:VMWARE虚拟机安装系统提示CPU已被客户机操作系统禁用 改正:找到虚拟机的位置找到下图灰色的部分:打开 .vmx后缀的操作系统配置文件,加入以下代码: cpuid.1.eax = :: 2. ...

  4. NeurIPS 2019 Spotlight | Cascade RPN,结构的艺术带来极致的提升

    论文提出Cascade RPN算法来提升RPN模块的性能,该算法重点解决了RPN在迭代时anchor和feature不对齐的问题,论文创新点足,效果也很惊艳,相对于原始的RPN提升13.4%AR 论文 ...

  5. 全国职业技能大赛信息安全管理与评估-MySQL爆破脚本

    DEMO: #coding=utf-8 import MySQLdb class MSSQL: def __init__(self,host,user,pwd): self.host = host s ...

  6. jwt(JSON Web Tokens)的一道题目代码分析

    题目链接https://github.com/wonderkun/CTF_web/tree/5b08d23ba4086992cbb9f3f4da89a6bb1346b305/web300-6 参考链接 ...

  7. VirtualBox 安装 Centos8 使用 Xshell 连接

    1.下载CentOS CentOS下载地址:https://wiki.centos.org/Download 这里选择本地安装包,网络安装包在安装时需要在线下载资源比较慢 2.安装VirtualBox ...

  8. sql-lib闯关51-60

    第五十一关 这一关和三十八关基本一样 ,堆叠注入问题  只不过是字符型                  ?sort=1';create table test51 like users;%23 看数据 ...

  9. Centos7部署k8s[v1.16]高可用[keepalived]集群

    实验目的 一般情况下,k8s集群中只有一台master和多台node,当master故障时,引发的事故后果可想而知. 故本文目的在于体现集群的高可用,即当集群中的一台master宕机后,k8s集群通过 ...

  10. 模块 subprocess 交互shell

    subprocess 交互shell 执行shell命令, 与操作系统交互 三种执行命令的方法 subprocess.run(*popenargs, input=None, timeout=None, ...