zoukankan      html  css  js  c++  java
  • GCD 延时执行 栅栏方法 ,快速迭代,只执行一次代码,GCD执行完一个任务在执行其他任务

     1.GCD 延时执行:dispatch_after

    2.GCD 快速迭代:dispatch_apply

    3.GCD 栅栏方法:dispatch_barrier_async

    4.GCD 代码只执行一次:

    1.GCD 延时执行:dispatch_after

    注意:这种方法只适用于大概2秒的时间,并不非常精确,这中方法是2秒之后把任务添加到主队列,执行时间和结束时间并不确定。

    /**
     * 延时执行 dispatch_after
     */
    - (void)after {
        NSLog(@"begin");
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            // 2秒后异步到主队列开始执行
            NSLog(@"2秒后:%@",[NSThread currentThread]);
        });
        
        NSLog(@"end");
    }
    

      

    2.GCD 快速迭代:dispatch_apply

    一般我们会用for循环遍历,dispatch_apply会将指定的任务追加到指定的队列中,并等待全部队列执行结束。

    如果是在串行队列中使用 dispatch_apply,那么就和 for 循环一样,按顺序同步执行。可这样就体现不出快速迭代的意义了。

    我们可以利用并发队列进行异步执行。比如说遍历 0~5 这6个数字,for 循环的做法是每次取出一个元素,逐个遍历。
     
    dispatch_apply 可以 在多个线程中同时(异步)遍历多个数字。

    无论是在串行队列,还是异步队列中,dispatch_apply 都会等待全部任务执行完毕
     
    /**
     * 快速迭代方法 dispatch_apply
     */
    - (void)apply {
    //    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_queue_t queue = dispatch_queue_create("hzw", DISPATCH_QUEUE_SERIAL);
        
        NSLog(@"begin");
        dispatch_apply(5, queue, ^(size_t index) {
            NSLog(@"序列index:%zd-----线程:%@",index, [NSThread currentThread]);
        });
        NSLog(@"end");
    }
    

      

    把上面创建线程queue的注释互换一下,在并发队列中异步执行任务,打印如下:

    所以各个任务的执行时间长短不定,最后结束顺序也不定。执行任务所在的线程也不一定,但是end在最后执行。这是因为dispatch_apply函数会等待全部任务执行完毕。

    3.GCD 栅栏方法:dispatch_barrier_async

      有时候我们会有这样的需求我们需要执行ABCD等若干个任务,等ABCD全部完成后在执行E任务刷新界面或者其他操作,(ABCD任务执行顺序无要求,但要全部执行完,当然NSOperationQueue也很容易),刷新成功之后再执行FG操作,这时候用栅栏方法就派上很大用场了。

    /**
     * 栅栏方法 dispatch_barrier_async
     */
    - (void)barrier {
    //    在执行完栅栏前面的操作之后,才执行栅栏操作,最后再执行栅栏后边的操作
        dispatch_queue_t queue = dispatch_queue_create("hzw", DISPATCH_QUEUE_CONCURRENT);
        
        dispatch_async(queue, ^{
            // 追加任务1
            for (int i = 0; i < 2; ++i) {
                NSLog(@"任务1---%@",[NSThread currentThread]);
            }
        });
        dispatch_async(queue, ^{
            // 追加任务2
            for (int i = 0; i < 2; ++i) {
                NSLog(@"任务2---%@",[NSThread currentThread]);
            }
        });
        
        dispatch_barrier_async(queue, ^{
            // 追加任务 barrier
            for (int i = 0; i < 2; ++i) {
                NSLog(@"栅栏任务---%@",[NSThread currentThread]);
            }
        });
        
        dispatch_async(queue, ^{
            // 追加任务3
            for (int i = 0; i < 2; ++i) {
                NSLog(@"任务3---%@",[NSThread currentThread]);
            }
        });
    }
    

      

    4.GCD 代码只执行一次:dispatch_once

    dispatch_once 函数能保证某段代码在程序运行过程中只被执行1次,并且即使在多线程的环境下,dispatch_once也可以保证线程安全。

    /**
     * 一次性代码(只执行一次)dispatch_once
     */
    - (void)once {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            //执行代码
        });
    }
    

      

  • 相关阅读:
    Css进阶
    Css布局
    遇到的小问题
    MySQL 8.017连接Navicat中出现的问题
    ConcurrentHashMap图文源码解析
    HashMap图文源码解析
    接口和抽象类
    dependencies 和 devDependencies
    2020.7.7第二天
    2020.7.6第一天
  • 原文地址:https://www.cnblogs.com/huangzhenwei/p/9728094.html
Copyright © 2011-2022 走看看