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

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

作者: 同心圆圈 | 来源:发表于2017-06-15 10:58 被阅读24次

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]);
    });

相关文章

  • ios多线程操作— GCD延迟操作和相关使用方法

    ios多线程操作— GCD延迟操作和相关使用方法 0x01.iOS版本 使用GCD函数可以进行延时操作,该函数为 ...

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

    GCD组函数的使用 使用场景:在开发中遇到过这样的功能,某个界面列表上面是资源信息,下面是评论列表信息,而且资源信...

  • 7.3 多线程-GCD

    多线程-GCD 多线程-GCD-串行并行 多线程-GCD.png GCD-线程的通讯、延时操作、定时器 GCD-线...

  • 多线程02

    多线程2 GCD队列组: 基本使用: 常用函数 队列和组队列的区别 队列:封装任务,添加任务到队列 组队列:封装任...

  • iOS基础篇-GCD死锁

    GCD死锁概念: 使用GCD多线程编程时,如果同步函数dispatch_sync(),目标queue为当前queu...

  • GCD同步阻塞原理

    GCD因为功能强大,操作简便,成为苹果官方推荐使用的多线程API。然而GCD也难只要逃涉及多线程就会遇到的死锁问题...

  • iOS多线程使用

    这里介绍多线程中GCD和NSOperationQueue的使用。 GCD 主线程,任何需要刷新UI的操作都要在主线...

  • Swift多线程:GCD进阶,单例、信号量、任务组

    Swift多线程:GCD进阶,单例、信号量、任务组 Swift多线程:GCD进阶,单例、信号量、任务组

  • iOS四种多线程的基本使用

    1.pthread 实现多线程操作(不常使用) 2.NSThread实现多线程 3.多线程之GCD讲解 模拟两个异...

  • 多线程知识总结

    一:多线程概念知识: 二,NSThread 的使用场景(1)耗时操作放在子线程中执行 三.多线程安全 四.GCD ...

网友评论

      本文标题:GCD - 网络多线程操作(组函数的使用)

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