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