美文网首页
iOS GCD中一些系统提供的常用的dispatch方法

iOS GCD中一些系统提供的常用的dispatch方法

作者: CrystalZhu | 来源:发表于2020-02-18 09:38 被阅读0次

    1.dispatch_after 延时添加到队列

    dispatch_time_t delayTime3 = dispatch_time(DISPATCH_TIME_NOW, 3*NSEC_PER_SEC);
    dispatch_time_t delayTime2 = dispatch_time(DISPATCH_TIME_NOW, 2*NSEC_PER_SEC);
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    NSLog(@"current task");
    dispatch_after(delayTime3, mainQueue, ^{
      NSLog(@"3秒之后添加到队列");
    });
    dispatch_after(delayTime2, mainQueue, ^{
      NSLog(@"2秒之后添加到队列");
    });
    NSLog(@"next task");
    

    输出:
    current task -> next task -> 2秒之后 -> 3秒之后
    dispatch_after 只是延时提交block并不是延时执行,并不能做到精准控制

    1. dispatch_apply 在给定的队列上多次执行某一任务,在主线程直接调用会阻塞主线程去执行block中的任务
      dispatch_apply函数的功能: 把一项任务提交到队列中多次执行,队列可以是串行的也可以是并行的,dispatch_apply不会立刻返回,在执行完block中的任务后才会返回,是同步执行的函数.
      dispatch_apply正确使用方法: 为了不阻塞主线程,一般把dispatch_apply放在异步队列中调用,然后执行完成后通知主线程.
    dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
    NSLog(@"current task");
    dispatch_async(globalQueue, ^{
      dispatch_queue_t applyQueue = dispatch_get_global_queue(0, 0);
      //第一个参数: 3  block的执行次数
      //第二个参数: applyQueue   block任务提交到的队列
      //第三个参数: block需要重复执行的任务
      dispatch_apply(3, applyQueue, ^ (size_t index) {
        NSLog(@"current index %@", @index);
        sleep(1);
      });
      NSLog(@"dispatch_apply 执行完成");
      dispatch_queue_t mainQueue = dispatch_get_main_queue();
      dispatch_async(mainQueue, ^{
        NSLog(@"回到主线程更新UI");
      });
    });
    NSLog(@"next task"):
    

    输出:
    current task -> next task -> current index 0 -> current index 1 -> current index 2 -> dispatch apply 执行完成 -> 回到主线程更新UI
    嵌套使用dispatch_apply会导致死锁

    3.dispatch_once 保证app运行期间 block中的代码只执行一次
    经常使用的场景 单例

    //GCD完成单例功能
    +(shareManager *) shareManager{
      static dispatch_once_t onceToken;
      dispatch_once(&onceToken, ^{
      shareManager = [[self alloc] init];
    });
    return shareManager;
    }
    //ARC下,非GCD,实现单例功能
    +(shareManager *)shareManager{
      @synchronized (self){
        if (! shareManager){
          shareManager = [[self alloc] init];
        }
      }
      return shareManager;
    }
    

    4.dispatch_barrier_async 栅栏的作用
    功能: 是在并行队列中,等待在dispatch_barrier_async之前加入的队列全部执行完成之后(这些任务是并发执行),再执行dispatch_barrier_async中的任务,dispatch_barrier_async中的任务执行完成以后,再去执行在dispatch_barrier_async之后加入队列中的任务(这些任务是并发执行的).

    dispatch_queue_t conCurrentQueue = dispatch_queue_create("com.dullgrass.conCurrentQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(conCurrentQueue, ^{
      NSLog(@"dispatch 1");
    });
    dispatch_async(conCurrentQueue, ^{
      NSLog(@"dispatch 2");
    });
    dispatch_barrier_async(conCurrentQueue, ^{
      NSLog(@"dispatch barrier");
    });
    dispatch_async(conCurrentQueue, ^{
      NSLog(@"dispatch 3");
    });
    dispatch_async(conCurrentQueue, ^{
      NSLog(@"dispatch 4");
    });
    

    输出:
    dispatch 1 -> dispatch 2 -> dispatch barrier -> dispatch 3 -> dispatch 4

    队列决定了是并发还是串行, 同步异步决定了是否开启新的线程

    同步异步 concurrent serial 主队列(只有主线程,串行)
    sync 不开启新线程, 串行 不开启新线程,串行 不开启新线程,串行
    async 开启新线程, 并发 开启新线程,串行 不开启新线程,串行

    相关文章

      网友评论

          本文标题:iOS GCD中一些系统提供的常用的dispatch方法

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