NSOperationQueue使用

作者: 辛乐 | 来源:发表于2018-12-15 15:56 被阅读13次

参考:https://www.jianshu.com/p/4b1d77054b35
只有异步开启子线程,在子线程中执行耗时任务才会避免阻碍主线程的UI界面
常用的方法如下:

//1.0 GCD 常用方式异步并发+与主线程交互
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //耗时长的操作
        
        //子线程与主线程通信
        dispatch_async(dispatch_get_main_queue(), ^{
            //主线程界面刷新
        });
    });
    
    //2.0 NSOperationQueue 常用方式异步并发+与主线程交互
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperationWithBlock:^{
        //耗时长的操作
        
        //子线程与主线程通信
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            //主线程界面刷新
            
        }];
    }];

NSOperationQueue队列中可以同时执行多个任务,至于NSOperationQueue的取消暂停还没遇到实际的需求,暂缓待记~~~

//创建队列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    queue.maxConcurrentOperationCount = 5;//最大并发的任务数(并不一定是线程数,一个任务中可能多个线程)
    
    NSArray *arr = @[@"a",@"b",@"c",@"d"];
    NSBlockOperation *lastOp;
    for (NSString *str in arr) {
     
        NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
            NSData *data;
            data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://www.baidu.com"]];
            
            [self.mArr addObject:str];
//            [NSThread sleepForTimeInterval:2.0];
            LOG(@"~~~任务%@:%@ %@~~~%@",str,data,self.mArr,[NSThread currentThread]);
        }];
        
        //添加依赖
        if (lastOp) {
            [op addDependency:lastOp];
            lastOp = op;
        }else{
            lastOp = op;
        }
        [queue addOperation:op];
    }

    [queue waitUntilAllOperationsAreFinished];//等待所有的任务结束,这个会阻塞当前的线程
    
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        UILabel *label= [self.view viewWithTag:100];
        label.text = [NSString stringWithFormat:@"任务结束%@",self.mArr];
        LOG(@"~~~任务结束:%@~~~%@",self.mArr,[NSThread currentThread]);
    }];

实际的af网络请求也是个异步的操作,此时需要的是实际数据的接受完成再去重新刷新UI,这时候可以借助信号量,将AF的异步请求强制处理成同步,这时候达到的效果:异步串行

 NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    queue.maxConcurrentOperationCount = 5;//最大并发的任务数(并不一定是线程数,一个任务中可能多个线程)
    
    NSArray *arr = @[@"eth",@"btc",@"bts",@"nas",@"ltc"];
    NSBlockOperation *lastOp;
    for (NSString *str in arr) {
        /*任务a */
        NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
           //创建信号量
            dispatch_semaphore_t sema = dispatch_semaphore_create(0);
            [self getDepositNoticeWithAssetCode:str LeaveBlock:^{
                     //信号量+1
                    dispatch_semaphore_signal(sema);
            }];
            //当前线程根据信号量的值在等待(信号量值为0在等待,否则往下执行并且减去1)
            dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
        }];
        
        //添加依赖
        if (lastOp) {
            [op addDependency:lastOp];
            lastOp = op;
        }else{
            lastOp = op;
        }
        [queue addOperation:op];
        
        if ([str isEqualToString:arr.lastObject]) {
            
            NSBlockOperation *endOp = [NSBlockOperation blockOperationWithBlock:^{
                [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                    LOG(@"~~~任务abcd执行完成~~~");
                }];
            }];
            [endOp addDependency:op];
            [queue addOperation:endOp];
        }
    }
    
    //加信号量这里线程已经阻塞,不会执行(可以放开测试)
//   [queue waitUntilAllOperationsAreFinished];//等待所有的任务结束,这个会阻塞当前的线程
    LOG(@"~~~我就是想看看会不会阻塞当前的线程~~~");

相关文章

网友评论

    本文标题:NSOperationQueue使用

    本文链接:https://www.haomeiwen.com/subject/akeahqtx.html