GCD - 网络多线程操作(组函数的使用)

GCD组函数的使用

使用场景:在开发中遇到过这样的功能,某个界面列表上面是资源信息,下面是评论列表信息,而且资源信息和评论列表信息不是同一个接口,必须等两者数据都获取完毕的时候才能刷新UI

1、dispatch_group_t和dispatch_group_async

    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    // 1、
    dispatch_group_async(group, queue, ^{
        [NetworkTool postAlloc:@"http://www.jianshu.com/" parameters:nil successed:^(id json) {
            NSLog(@"http://www.jianshu.com/ --- success");
        } failure:^(NSError *error) {
            NSLog(@"http://www.jianshu.com/ --- failure");
        }];
    });

    // 2、
    dispatch_group_async(group, queue, ^{
        [NetworkTool postAlloc:@"https://www.baidu.com/" parameters:nil successed:^(id json) {
            NSLog(@"https://www.baidu.com/ --- success");
        } failure:^(NSError *error) {
            NSLog(@"https://www.baidu.com/ --- failure");
        }];
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"dispatch_group_notify --- 结束");
    });

输出结果

[ViewController.m:278行] dispatch_group_notify --- 结束
[ViewController.m:264行] http://www.jianshu.com/ --- failure
[ViewController.m:271行] https://www.baidu.com/ --- success

说明:这时候问题来了, [NetworkTool postAlloc:parameters:successed:failure]这是封装的请求方法(异步函数),大家都知道,异步函数不会阻塞主线程,不等异步函数执行完毕,dispatch_group_notify里的代码就开始执行了。
解决方法:请看下面的2、和3、实现。

2、dispatch_group_enter和dispatch_group_leave

 dispatch_group_t group = dispatch_group_create();
   
    dispatch_group_enter(group);
    [NetworkTool postAlloc:@"http://www.jianshu.com/" parameters:nil successed:^(id json) {
        dispatch_group_leave(group);
        NSLog(@"http://www.jianshu.com/ --- success");
    } failure:^(NSError *error) {
        dispatch_group_leave(group);
        NSLog(@"http://www.jianshu.com/ --- failure");
    }];
    
    dispatch_group_enter(group);
    [NetworkTool postAlloc:@"https://www.baidu.com/" parameters:nil successed:^(id json) {
        dispatch_group_leave(group);
        NSLog(@"https://www.baidu.com/ --- success");
    } failure:^(NSError *error) {
        dispatch_group_leave(group);
        NSLog(@"https://www.baidu.com/ --- failure");
    }];
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"dispatch_group_notify --- 结束");
    });
        

输出结果

[ViewController.m:233行] http://www.jianshu.com/ --- failure
[ViewController.m:239行] https://www.baidu.com/ --- success
[ViewController.m:246行] dispatch_group_notify --- 结束

3、dispatch_group_t、dispatch_group_async和dispatch_semaphore_t结合实现

  //使用GCD的信号量 dispatch_semaphore_t 创建同步请求
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    // 1、
    dispatch_group_async(group, queue, ^{
        dispatch_semaphore_t semaphore= dispatch_semaphore_create(0);
        //模拟网络多线程耗时操作
        dispatch_group_async(group, queue, ^{
            sleep(5);
            NSLog(@"%@-->线程1结束。。。",[NSThread currentThread]);
            dispatch_semaphore_signal(semaphore);
        });
        NSLog(@"%@-->1结束。。。",[NSThread currentThread]);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    });
    
    // 2、
    dispatch_group_async(group, queue, ^{
        dispatch_semaphore_t semaphore= dispatch_semaphore_create(0);
        
        //模拟网络多线程耗时操作
        dispatch_group_async(group, queue, ^{
            sleep(3);
            NSLog(@"%@-->线程2结束。。。",[NSThread currentThread]);
            dispatch_semaphore_signal(semaphore);
        });
        
        NSLog(@"%@-->2结束。。。",[NSThread currentThread]);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    });
    
    dispatch_group_notify(group, queue, ^{
        NSLog(@"%@-->全部结束。。。",[NSThread currentThread]);
    });

    dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
        NSLog(@"%@---全部结束。。。",[NSThread currentThread]);
        
    });

输出结果

[ViewController.m:197行] <NSThread: 0x6000000755c0>{number = 6, name = (null)}-->1结束。。。
[ViewController.m:212行] <NSThread: 0x61000007f6c0>{number = 7, name = (null)}-->2结束。。。
[ViewController.m:208行] <NSThread: 0x608000274dc0>{number = 10, name = (null)}-->线程2结束。。。
[ViewController.m:194行] <NSThread: 0x600000264f40>{number = 11, name = (null)}-->线程1结束。。。
[ViewController.m:217行] <NSThread: 0x6000000755c0>{number = 6, name = (null)}-->全部结束。。。

其他的实现方法有(OSSpinLock 、pthread_mutex_t、NSLock等):

#import <libkern/OSAtomic.h>
//#import <pthread.h>
     __block OSSpinLock spinLock = OS_SPINLOCK_INIT;
    //__block pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER
    //NSLock *lock = [NSLock new];
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    // 1、
    dispatch_group_async(group, queue, ^{
        //模拟网络多线程耗时操作
        OSSpinLockLock(&spinLock);
        //pthread_mutex_lock(&mutex);
        //[lock lock];
        dispatch_group_async(group, queue, ^{
            sleep(5);
            NSLog(@"%@-->线程1结束。。。",[NSThread currentThread]);     
        });
        NSLog(@"%@-->1结束。。。",[NSThread currentThread]);
        OSSpinLockUnlock(&spinLock);
        //pthread_mutex_unlock(&mutex);
        //[lock unlock];
    });
    
    // 2、
    dispatch_group_async(group, queue, ^{
        OSSpinLockLock(&spinLock);
        
        //模拟网络多线程耗时操作
        dispatch_group_async(group, queue, ^{
            sleep(3);
            NSLog(@"%@-->线程2结束。。。",[NSThread currentThread]);
        });
        NSLog(@"%@-->2结束。。。",[NSThread currentThread]);
        OSSpinLockUnlock(&spinLock);
    });
    
    dispatch_group_notify(group, queue, ^{
        NSLog(@"%@-->全部结束。。。",[NSThread currentThread]);
    });
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容