美文网首页
iOS GCD基础篇 - 同步、异步,并发、并行的理解

iOS GCD基础篇 - 同步、异步,并发、并行的理解

作者: 路漫漫其修远兮Wzt | 来源:发表于2018-04-16 15:29 被阅读15次

    转载自:https://blog.csdn.net/amm28824/article/details/54564378

    现在讲一下dispatch_group的概念以及几种场景下的使用
    1、关于dispatch_group

    把一组任务提交到队列中,这些队列可以不相关,然后监听这组任务完成的事件。

    最常见的几个方法:

    1. dispatch_group_create创建一个调度任务组
    2. dispatch_group_async 把一个任务异步提交到任务组里
    3. dispatch_group_enter/dispatch_group_leave 这种方式用在不使用dispatch_group_async来提交任务,且必须配合使用
      4.dispatch_group_notify 用来监听任务组事件的执行完毕
      5.dispatch_group_wait 设置等待时间,在等待时间结束后,如果还没有执行完任务组,则返回。返回0代表执行成功,非0则执行失败

    2、实际使用场景  
    场景1:

    现在有4个任务,任务1、任务2、任务3、任务4. 任务3必须在任务2之后,任务4必须在前3个任务都执行完成后,才能执行,并且需要在主线程更新UI。

    思路分析:

    任务3必须在任务2之后,所以这两个必须串行执行,同时,任务2和3整体可以和任务1并行执行,最后,任务4只能等待前3个任务全部执行完成,才能执行。这里就可以用group快速实现场景需求。

    代码实现:

     -(void)disGroup{
      dispatch_queue_t globalQuene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  
      dispatch_queue_t selfQuene = dispatch_queue_create("myQuene", 0);  
      dispatch_group_t group = dispatch_group_create();  
      dispatch_group_async(group, globalQuene, ^{  
         NSLog(@"run task 1");  
      });  
      dispatch_group_async(group, selfQuene, ^{  
         NSLog(@"run task 2");  
      });  
     dispatch_group_async(group, selfQuene, ^{  
         NSLog(@"run task 3");  
     });  
     dispatch_group_notify(group, dispatch_get_main_queue(), ^{  
       NSLog(@"run task 4");   });  
    }  
    

    执行结果如下:(结果1和结果2是一样的,只是1和2的顺序区别)


    image

    结果1 或

    image

    结果2

    总结: 1和(2、3)是并行执行关系,2、3是串行执行关系,且3肯定在2之后,而4在(1、2、3)全部完成之后才会执行。

    2、dispatch_group_enter(group)、dispatch_group_leave(group) 何时使用

    理论上讲,这两个方法其实就是:手动管理group关联的block的运行状态(或计数),并且使用时必须保证进入和退出group次数匹配。

    所以:A和B两种使用方式可以讲是等价的

      A)  
      dispatch_group_async(group, queue, ^{   
      // 。。。   
      });   
    
      B)   
      dispatch_group_enter(group);  
      dispatch_async(queue, ^{  
      //。。。  
      dispatch_group_leave(group);  
      });  
    

    所以,这种用法和直接使用dispatch_group_notify一定程度上是等价的,大家可以自己选择使用。

    场景2:

    有3个异步请求任务,任务1、2、3,在3个任务全部完成之后,需要执行任务4,用以显示界面数据。

    用 dispatch_group_enter、 dispatch_group_leave 实现:

      -(void)disGroupEnterAndLeave{  
      dispatch_queue_t globalQuene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  
      dispatch_group_t group = dispatch_group_create();  
    
      //任务1  
      dispatch_group_enter(group);  
      dispatch_async(globalQuene, ^{  
         NSLog(@"run task 1");  
         sleep(1);  
         dispatch_group_leave(group);  
      });  
    
      //任务2  
      dispatch_group_enter(group);  
      dispatch_async(globalQuene, ^{  
         NSLog(@"run task 2");  
         sleep(2);  
         dispatch_group_leave(group);  
      });  
    
      //任务3  
      dispatch_group_enter(group);  
      dispatch_async(globalQuene, ^{  
         NSLog(@"run task 3");  
         sleep(3);  
         dispatch_group_leave(group);  
      });  
    
      //一直等待完成  
      dispatch_group_wait(group, DISPATCH_TIME_FOREVER);  
    
      //任务3  
     dispatch_group_notify(group, dispatch_get_main_queue(), ^{  
         NSLog(@"run task 4");  
      });  
    
      }  
    

    执行结果:

    image

    3个任务是并行执行,且一共花费3s执行,然后才执行任务4。

    当然,如果这样想串行执行3个任务,只需要把 **全局队列 **换成 **自定义队列 **即可。

    相关文章

      网友评论

          本文标题:iOS GCD基础篇 - 同步、异步,并发、并行的理解

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