iOS 实现界面多个网络请求全部结束后主线程处理结果

1. 实现方法一: dispatch_queue_t + dispatch_group_t

- (void)startMultiRequest1 {
    
// 创建全局队列
    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, ^{
    // 请求一
        [self request:1 group:group];
    });
    dispatch_group_async(group, queue, ^{
    // 请求二
        [self request:2 group:group];
    });
    dispatch_group_async(group, queue, ^{
    // 请求三
        [self request:3 group:group];
    });
    
    dispatch_group_notify(group, queue, ^{

        NSLog(@"请求完成");
    });
}

- (void)request:(NSInteger)inter group:(dispatch_group_t)group {
    
    dispatch_group_enter(group);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
       
        NSLog(@"请求 %ld", (long)inter);
        NSLog(@"请求 %ld", (long)inter);
        NSLog(@"%@", [NSThread currentThread]);
        
        dispatch_group_leave(group);
    });
}

结果:

2019-05-17 15:08:37.157928+0800 Object-C[38191:2772580] 可用10.0
2019-05-17 15:08:39.591520+0800 Object-C[38191:2772710] 请求 3
2019-05-17 15:08:39.591522+0800 Object-C[38191:2772706] 请求 2
2019-05-17 15:08:39.591538+0800 Object-C[38191:2772711] 请求 1
2019-05-17 15:08:39.591698+0800 Object-C[38191:2772710] 请求 3
2019-05-17 15:08:39.591737+0800 Object-C[38191:2772706] 请求 2
2019-05-17 15:08:39.591756+0800 Object-C[38191:2772711] 请求 1
2019-05-17 15:08:39.592028+0800 Object-C[38191:2772710] {number = 3, name = (null)}
2019-05-17 15:08:39.592039+0800 Object-C[38191:2772706] {number = 4, name = (null)}
2019-05-17 15:08:39.592070+0800 Object-C[38191:2772711] {number = 5, name = (null)}
2019-05-17 15:08:39.592695+0800 Object-C[38191:2772711] 请求完成

注意: 使用GCD group实现多请求关键是:
dispatch_group_enter(group) dispatch_group_leave(group)
两个方法的应用,若是直接使用group及异步处理是无法实现的。

group的概念了解:group的设计就是为了方便我们执行完一系列的任务之后再执行其他的任务,但是不能忽视的是,这里的任务是有要求的,这里的任务必须要是同步执行的!!如果任务是异步的,group只会执行完任务里面异步之前的代码以及分发异步任务就返回了!!也就代表分发group的当前这个任务完成了!但事实却是这个任务的一部分子任务在其他线程执行了,而且不一定已执行结束返回。

补充:我们可以注意到GCD实现的一些细节,在这里group到另外异步方法的执行,GCD并没有重新创建新的线程,而是重用了group已创建的线程。`

2. 实现方法二:dispatch_semaphore_t信号量

子线程中执行多个任务,利用信号量对线程进行阻塞,所有任务执行结束后发送信号,继续执行之后任务

- (void)startMultiRequest2 {
    
    dispatch_semaphore_t sem = dispatch_semaphore_create(0);
    
    
    NSInteger commandCount = 5;

    __block NSInteger httpFinishCount = 0;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSLog(@"开始任务 thred: %@", [NSThread currentThread]);
        
        for (int i = 0; i < 5; i++) {
            
            [self request:i block:^{

                if (++httpFinishCount == commandCount) {
                    dispatch_semaphore_signal(sem);
                }
            }];
        }
        
        //如果全部请求没有返回则该线程会一直阻塞
        dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
        NSLog(@"所有任务结束! thread: %@", [NSThread currentThread]);
        dispatch_async(dispatch_get_main_queue(), ^{
            
            NSLog(@"更新UI/::>/::>/::>/::>!");
        });
    });
}

- (void)request:(NSInteger)inter block:(void (^)(void))block {
    
    dispatch_sync(dispatch_get_global_queue(0, 0), ^{
       
        NSLog(@"请求 %ld", (long)inter);
        NSLog(@"请求 %ld", (long)inter);
        NSLog(@"%@", [NSThread currentThread]);

        //全部请求返回才触发signal
        block();
    });
}

你可能感兴趣的:(iOS 实现界面多个网络请求全部结束后主线程处理结果)