iOS GCD之项目实战

2019-06-19  本文已影响0人  不会写代码的尬先生

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

可能我们会想到用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信号

上一篇下一篇

猜你喜欢

热点阅读