专栏首页iOSerNSOperationQueue队列中操作依赖相关思考

NSOperationQueue队列中操作依赖相关思考

  • 添加依赖后,队列中网络请求任务有依赖关系时,任务结束判定以数据返回为准还是以发起请求为准?
  • waitUntilFinished方法容易误解。

依赖关系

//
//  ViewController.m
//  OperationTest0108
//
//  Created by LongMa on 2020/1/8.
//

#import "ViewController.h"
#import <AFNetworking/AFNetworking.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self testQueue];
}

- (void)testQueue{
    NSOperationQueue *lQ = [[NSOperationQueue alloc] init];
    
    //任务最大并发数,与是否开启子线程无关。
//    lQ.maxConcurrentOperationCount = 1;
    
    NSBlockOperation *lOp0 = [NSBlockOperation blockOperationWithBlock:^{
        AFHTTPSessionManager *lMng = [AFHTTPSessionManager manager];
        [lMng POST:@"https://www.baidu.com" parameters:@{
            @"mapId" : @"1"
        } progress:^(NSProgress * _Nonnull uploadProgress) {
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            NSLog(@"0 suc");
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"0 error");
        }];
        
        NSLog(@"0 %@", [NSThread currentThread]);
    }];
    
    NSBlockOperation *lOp1 = [NSBlockOperation blockOperationWithBlock:^{
        AFHTTPSessionManager *lMng = [AFHTTPSessionManager manager];
               [lMng POST:@"https://www.baidu.com" parameters:@{
                   @"mapId" : @"1"
               } progress:^(NSProgress * _Nonnull uploadProgress) {
                   
               } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                   NSLog(@"1 suc");
               } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                   NSLog(@"1 error");
           }];
        
        NSLog(@"1 %@", [NSThread currentThread]);
    }];
    
    NSBlockOperation *lOp2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"2 %@", [NSThread currentThread]);
    }];
    
    [lOp0 addDependency:lOp1];
    
    NSLog(@"before add op");
    
    [lQ addOperations:@[lOp0] waitUntilFinished:NO];
    [lQ addOperations:@[lOp1] waitUntilFinished:NO];
    [lQ addOperations:@[lOp2] waitUntilFinished:NO];
}

@end

执行结果

2020-01-08 18:02:31.378260+0800 OperationTest0108[1583:527022] before add op
2020-01-08 18:02:31.378635+0800 OperationTest0108[1583:527045] 2 <NSThread: 0x283db43c0>{number = 4, name = (null)}
2020-01-08 18:02:31.379722+0800 OperationTest0108[1583:527047] 1 <NSThread: 0x283db4240>{number = 5, name = (null)}
2020-01-08 18:02:31.380265+0800 OperationTest0108[1583:527047] 0 <NSThread: 0x283db4240>{number = 5, name = (null)}
2020-01-08 18:02:31.915236+0800 OperationTest0108[1583:527022] 0 error
2020-01-08 18:02:31.921841+0800 OperationTest0108[1583:527022] 1 error

由上面log可知:任务结束判定以发起请求为准!数据返回是异步的,不受依赖关系影响!

waitUntilFinished方法

当把上面代码

[lQ addOperations:@[lOp0] waitUntilFinished:NO];

改为

[lQ addOperations:@[lOp0] waitUntilFinished:YES];

时, log如下,没有正常执行操作:

2020-01-08 18:03:55.308276+0800 OperationTest0108[1587:527738] before add op

分析: waitUntilFinished方法定义为: If YES, the current thread is blocked until all of the specified operations finish executing. If NO, the operations are added to the queue and control returns immediately to the caller. 当为YES时,当前线程被阻塞,直到被添加的操作执行完毕。上面代码使线程依赖于lOp0执行完毕,而lOp0的执行依赖于lOp1执行完毕。由于lOp1比lOp0加入队列更晚。当上面代码被执行时,线程在等lOp0执行完毕,而此时lOp1还没被加入队列中,即lOp1还没开始执行,所以线程一直处于阻塞状态!当然,合理利用waitUntilFinished方法,也能实现想要的特殊效果。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • iOS 多线程 - NSOperation

    hrscy
  • iOS多线程:『NSOperation、NSOperationQueue』详尽总结

    程序员充电站
  • iOS多线程:『NSOperation、NSOperationQueue』详尽总结

    https://juejin.im/post/5a9e57af6fb9a028df222555”

    iOSSir
  • iOS - 多线程(四):NSOperation

    NSOperation 需要和 NSOperationQueue 配合使用来实现多线程方案。单独使用 NSOperation 的话, 它是属于同步操作, 并不具...

    师大小海腾
  • 多线程-NSOperation和NSOperationQueue

    NSOperation类是用来封装在单个任务相关的代码和数据的抽象类。NSOperation 是苹果公司对 GCD 的封装,完全面向对象,所以使用起来更好理解。...

    進无尽
  • iOS--多线程之NSOperation

    用户1941540
  • 多线程之NSOperation小结

    相比NSInvocationOperation推荐使用NSBlockOperation,代码简单,同时由于闭包性使它没有传参问题。

    woopDast1
  • 浅析iOS多线程编程之NSOperation

    VV木公子
  • 推荐:多线程的实现方式及经典示例

    iOS中实现多线程的技术方案 ? pthread 实现多线程操作 代码实现: void * run(void *param) { for (NSInte...

    春哥大魔王
  • iOS多线程之四:NSOperation的使用

    一、NSOperation NSOperation是苹果公司对GCD的封装,完全面向对象,但是比GCD拥有更强的可控性和代码可读性。所以使用起来更好理解。 ...

    s_在路上
  • iOS多线程——你要知道的NSOperation都在这里你要知道的iOS多线程NSThread、GCD、NSOperation、RunLoop都在这里

    你要知道的iOS多线程NSThread、GCD、NSOperation、RunLoop都在这里 转载请注明出处 https://cloud.tencent.co...

    WWWWDotPNG
  • iOS学习——(转)多线程

    转载自:iOS多线程全套:线程生命周期,多线程的四种解决方案,线程安全问题,GCD的使用,NSOperation的使用

    mukekeheart
  • 浅谈如何在项目中处理页面中的多个网络请求

    在开发中很多时候会有这样的场景,同一个界面有多个请求,而且要在这几个请求都成功返回的时候再去进行下一操作,对于这种场景,如何来设计请求操作呢?今天我们就来讨论一...

    s_在路上
  • 阿里、字节:一套高效的iOS面试题( 多线程 GCD底层原理篇)

    dispatch_group_create() + dispatch_group_wait()

    会写bug的程序员
  • iOS多线程之GCD、OperationQueue 对比和实践记录

    在计算的早期,计算机可以执行的最大工作量是由 CPU 的时钟速度决定的。但是随着技术的进步和处理器设计的紧凑化,热量和其他物理约束开始限制处理器的最大...

    woopDast1
  • iOS--多线程之线程间通讯

    用户1941540
  • iOS面试题:SDWebImage原理

    减少网络流量,下载完图片后存储到本地,下载再获取同一张图片时,直接从本地获取,提升用户体验,能快速从本地获取呈现给用户。

    猿_人类
  • NSOperation的简单使用代码

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/...

    用户1451823
  • iOS 多线程总结

    ●进程是指在系统中正在运行的一个应用程序,就是一段程序的执行过程,我们可以理解为手机上的一个app。 ●每个进程之间是独立的,每个进程均运行在其专用且受保护的...

    赵哥窟

扫码关注云+社区

领取腾讯云代金券