zoukankan      html  css  js  c++  java
  • 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方法,也能实现想要的特殊效果。

    学无止境,快乐编码。 没有一种不经过蔑视、忍受和奋斗就可以征服的命运。
  • 相关阅读:
    mac上虚拟机:VMWare Fusion, VirtualBox, Parallels Desktop, CrossOver, Veertu
    linux使用其它用户 su
    CentOS7 rc.local开机开法启动
    taskkill
    Make sure that the controller has a parameterless public constructor.
    An Autofac Lifetime Primer
    Controlling Scope and Lifetime
    Instance scope
    Linq的TakeWhile的用法
    Git does not apply deleted files when merging an old branch into the master. How can I tell Git to apply deleted files?
  • 原文地址:https://www.cnblogs.com/Dast1/p/12168103.html
Copyright © 2011-2022 走看看