iOS GCD之项目实战

实际开发中我们可能会遇到这种需求:等待某几个网络请求结束再进行后续操作,比如一个页面需要先请求三个接口,都拿到数据以后再去做页面的渲染。

可能我们会想到用gcd的dispatch_group_t,再异步并发请求接口,最后notify处理,但运行结果并不是我们预想的那样,而是先打印了notifyblock里的内容,才打印两个网络请求的内容,这是因为网络请求本身就是异步的,此时group的notify并不会真正等到网络请求结束才去处理notify。

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        NSDictionary *param = [[NSDictionary alloc] initWithObjectsAndKeys:@"121", @"id",nil];
        [CSNetWoring sendPostNetWorkWithUrl:SPORT_ORUN_RESOURCE parameters:param progressBlock:^(NSProgress *progress) {
            
        } successBlock:^(id data) {
            NSLog(@"请求一");
            
        } failureBlock:^(NSString *error) {
            
        }];
        
    });
    dispatch_group_async(group, queue, ^{
        
        NSDictionary *param = [[NSDictionary alloc] initWithObjectsAndKeys:@"121", @"id",nil];
        
        [CSNetWoring sendPostNetWorkWithUrl:SPORT_ORUN_RESOURCE parameters:param progressBlock:^(NSProgress *progress) {
            
        } successBlock:^(id data) {
            NSLog(@"请求二");
            
        } failureBlock:^(NSString *error) {
            
        }];
    });

    dispatch_group_notify(group, queue, ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"请求完成");
        });
    });

打印结果:
请求完成
请求二或请求三(异步,不确定先后)

介绍两种实现方式
一是用 dispatch_group_enter和dispatch_group_leave在每次网络请求成对使用

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_enter(group);
    dispatch_group_async(group, queue, ^{
        NSDictionary *param = [[NSDictionary alloc] initWithObjectsAndKeys:@"121", @"id",nil];
        [CSNetWoring sendPostNetWorkWithUrl:SPORT_ORUN_RESOURCE parameters:param progressBlock:^(NSProgress *progress) {
            
        } successBlock:^(id data) {
            NSLog(@"请求一");
            dispatch_group_leave(group);
            
        } failureBlock:^(NSString *error) {
            
        }];
        
    });
    dispatch_group_enter(group);
    
    dispatch_group_async(group, queue, ^{
        
        NSDictionary *param = [[NSDictionary alloc] initWithObjectsAndKeys:@"121", @"id",nil];
        
        [CSNetWoring sendPostNetWorkWithUrl:SPORT_ORUN_RESOURCE parameters:param progressBlock:^(NSProgress *progress) {
            
        } successBlock:^(id data) {
            NSLog(@"请求二");
            dispatch_group_leave(group);
            
        } failureBlock:^(NSString *error) {
            
        }];
    });
    
    dispatch_group_notify(group, queue, ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            
            NSLog(@"请求完成");
            
        });
    });
打印顺序:
先打印      请求二或请求一(异步乱序)
最后打印  请求完成

第二种是用dispatch_group_t加dispatch_semaphore_t信号量

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    // 创建全局并行
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        
        NSDictionary *param = [[NSDictionary alloc] initWithObjectsAndKeys:@"121", @"id",nil];
        
        [CSNetWoring sendPostNetWorkWithUrl:SPORT_ORUN_RESOURCE parameters:param progressBlock:^(NSProgress *progress) {
            
        } successBlock:^(id data) {
            NSLog(@"请求一");
            dispatch_semaphore_signal(semaphore);
            
        } failureBlock:^(NSString *error) {
            
        }];
        
    });
    dispatch_group_async(group, queue, ^{
        
        NSDictionary *param = [[NSDictionary alloc] initWithObjectsAndKeys:@"121", @"id",nil];
        
        [CSNetWoring sendPostNetWorkWithUrl:SPORT_ORUN_RESOURCE parameters:param progressBlock:^(NSProgress *progress) {
            
        } successBlock:^(id data) {
            NSLog(@"请求二");
            dispatch_semaphore_signal(semaphore);
            
        } failureBlock:^(NSString *error) {
            
        }];
    });
    
    dispatch_group_notify(group, queue, ^{
        NSLog(@"请求三");
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"请求四");
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"请求完成");
            
        });
    });
打印顺序:

请求三
请求一和请求二乱序
请求四
请求完成

dispatch_semaphore_wait会一直阻塞线程直到网络请求成功收到dispatch_semaphore_signal信号

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一:base.h 二:block.h 1. dispatch_block_flags:DISPATCH_BLOCK...
    小暖风阅读 2,505评论 0 0
  • 一. 重点: 1.dispatch_queue_create(生成Dispatch Queue) 2.Main D...
    BestJoker阅读 1,599评论 2 2
  • 多线程概念 线程线程指的是:1个CPU执行的CPU命令列为一条无分叉路径 多线程这种无分叉路径不止一条,存在多条即...
    我系哆啦阅读 611评论 0 5
  • 一.进程&线程 进程:是程序执行过程中分配和管理资源的一个基本单位。 线程:是程序执行过程中任务调度和执行的一个基...
    wxhan阅读 544评论 0 3
  • 故乡很小!但故乡很能闹! 今年是第四届正月初一联欢会。我搭了顺风车,回去参加! 没有舞台,只有一个小广场。主持人没...
    溪语微声阅读 235评论 0 1