美文网首页
GCD队列组 dispatch_group

GCD队列组 dispatch_group

作者: 一个半吊子工程师 | 来源:发表于2020-10-16 15:22 被阅读0次

    异步执行几个耗时操作,当这几个操作都完成之后再回到主线程进行操作,就可以用到队列组了。

    队列组有下面几个特点:

    1. 所有的任务会并发的执行(不按序)。
    2. 所有的异步函数都添加到队列中,然后再纳入队列组的监听范围。
    3. 使用dispatch_group_notify函数,来监听上面的任务是否完成,如果完成, 就会调用这个方法。

    dispatch_group的关键函数如下:

    • dispatch_group_t队列组对象类
    • dispatch_group_async 先把任务放到队列中,然后再讲队列放入队列组
    • dispatch_group_notify 用于获取执行完毕回调
    • dispatch_wait回到当前线程继续执行后面的操作(会阻塞当前线程)
    • dispatch_group_enter 用于标志一个任务追加到group,执行一次,相当于- - group中未执行完毕任务数+1
    • dispatch_group_leave 用于标志一个任务离开了group,执行一次,相当于- group中未执行完毕任务数-1

    题1:
    有n个请求(耗时操作)分别异步执行,当这些请求全部执行完了回主线程刷新UI。
    队列组示例代码:

    - (void)testGroup {
        dispatch_group_t group =  dispatch_group_create();
     
        dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
            NSLog(@"队列组:有一个耗时操作完成!");
        });
     
        dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
            NSLog(@"队列组:有一个耗时操作完成!");
        });
     
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            NSLog(@"队列组:前面的耗时操作都完成了,回到主线程进行相关操作");
        });
    }
    

    打印结果如下:

    队列组:有一个耗时操作完成!
    队列组:有一个耗时操作完成!
    队列组:前面的耗时操作都完成了,回到主线程进行相关操作
    
    - (void)downloadImages {
    
        NSString *fileDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
    //                         stringByAppendingPathComponent:@"image"];
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        _imgGroup = dispatch_group_create();
        NSLog(@"start downloading");
    //图1
     dispatch_group_async(_imgGroup, globalQueue, ^{
      dispatch_group_enter(_imgGroup);
            NSString *filePath = [fileDir stringByAppendingPathComponent:@"image0.jpg"];
            [self downloadImageToPath:filePath url:self.imgURLs[0]];
        });
    //图2
      dispatch_group_async(_imgGroup, globalQueue, ^{
            dispatch_group_enter(_imgGroup);        
            NSString *filePath = [fileDir stringByAppendingPathComponent:@"image1.jpg"];
            [self downloadImageToPath:filePath url:self.imgURLs[1]];
        });
    //图3
        dispatch_group_async(_imgGroup, globalQueue, ^{
            dispatch_group_enter(_imgGroup);        
            NSString *filePath = [fileDir stringByAppendingPathComponent:@"image2.jpg"];
            [self downloadImageToPath:filePath url:self.imgURLs[2]];
        });
    //下载完成会调`dispatch_group_notify`通知刷新
        dispatch_group_notify(_imgGroup, globalQueue, ^{
            NSLog(@"finish download");
        });
    }
    
    - (void)downloadImageToPath:(NSString *)filePath url:(NSString *)url{
        AFURLSessionManager *sessionMgr = [[AFURLSessionManager alloc] initWithSessionConfiguration:self.sessionConfig];
        NSURL *imgURL = [NSURL URLWithString:url];
        NSURLRequest *request = [NSURLRequest requestWithURL:imgURL];
        NSURLSessionDownloadTask *downloadTask =
        [sessionMgr downloadTaskWithRequest:request
                                   progress:nil
                                destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {                                
                                    NSURL *documentURL = [NSURL fileURLWithPath:filePath];
                                    return documentURL;
                                } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {                         
                                    dispatch_group_leave(_imgGroup);
                                }];
        [downloadTask resume];
    }
    

    相关文章

      网友评论

          本文标题:GCD队列组 dispatch_group

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