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, ^{
        //执行代码
    });
}

  

 

posted @ 2018-09-30 09:48  黄啊  阅读(306)  评论(0编辑  收藏  举报