美文网首页
GCD学习总结

GCD学习总结

作者: quteng | 来源:发表于2019-06-18 09:26 被阅读0次

GCD容易混淆的概念

任务,同步,异步 ,串行队列,并发队列

任务就是要做的事情

同步和异步是用来执行任务的

串行队列和并发队列是用来存放任务的。


同步和异步

同步执行(sync)

同步添加任务到指定的队列中,在添加的任务执行结束之前,会一直等待,直到队列里面的任务完成之后再继续执行。

只能在当前线程中执行任务,不具备开启新线程的能力。

异步执行(async)

异步添加任务到指定的队列中,它不会做任何等待,可以继续执行任务。

可以在新的线程中执行任务,具备开启新线程的能力,但不一定会开新线程。

简单理解:

同步(sync)是一个人走路。

异步(async)就是可能不止一个人走路,不同步。


队列

串行队列(Serial Dispatch Queue)

每次只有一个任务被执行。让任务一个接着一个地执行。(只开启一个线程,一个任务执行完毕后,再执行下一个任务)

并发队列(Concurrent Dispatch Queue)

可以让多个任务并发(同时)执行。(可以开启多个线程,并且同时执行任务)

注意:并发队列的并发功能只有在异步(dispatch_async)函数下才有效

简单理解:

串行: 把任务串在一个串上,先进先出

并发:把任务串在多个串上,想执行哪个,执行哪个。


GCD 的使用步骤

1、创建一个队列(串行队列或并发队列)


// 串行队列的创建方法
dispatch_queue_tqueue= dispatch_queue_create("com.baidu.testQueue", DISPATCH_QUEUE_SERIAL);

// 并发队列的创建方法
dispatch_queue_tqueue= dispatch_queue_create("com.baidu.testQueue", DISPATCH_QUEUE_CONCURRENT);

// 主队列的获取方法
dispatch_queue_tqueue= dispatch_get_main_queue();

// 全局并发队列的获取方法
dispatch_queue_tqueue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

2、将任务追加到任务的等待队列中,然后系统就会根据任务类型执行任务(同步执行或异步执行)

// 同步执行任务创建方法
dispatch_sync(queue, ^{
// 这里放同步执行任务代码
});

// 异步执行任务创建方法
dispatch_async(queue, ^{
// 这里放异步执行任务代码
});
是否开启线程,和死锁

GCD 栅栏方法:dispatch_barrier_async

我们有时需要异步执行两组操作,而且第一组操作执行完之后,才能开始执行第二组操作。这样我们就需要一个相当于栅栏一样的一个方法将两组异步执行的操作组给分割起来,当然这里的操作组里可以包含一个或多个任务。这就需要用到dispatch_barrier_async方法在两个操作组间形成栅栏。

dispatch_barrier_async函数会等待前边追加到并发队列中的任务全部执行完毕之后,再将指定的任务追加到该异步队列中。然后在dispatch_barrier_async函数追加的任务执行完毕之后,异步队列才恢复为一般动作,接着追加任务到该异步队列并开始执行。


GCD 延时执行方法:dispatch_after

我们经常会遇到这样的需求:在指定时间(例如3秒)之后执行某个任务。可以用 GCD 的dispatch_after函数来实现。

需要注意的是:dispatch_after函数并不是在指定时间之后才开始执行处理,而是在指定时间之后将任务追加到主队列中。严格来说,这个时间并不是绝对准确的,但想要大致延迟执行任务,dispatch_after函数是很有效的。

/**
 * 延时执行方法 dispatch_after
 */
- (void)after {
    NSLog(@"currentThread---%@",[NSThread currentThread]);  // 打印当前线程
    NSLog(@"asyncMain---begin");
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        // 2.0秒后异步追加任务代码到主队列,并开始执行
        NSLog(@"after---%@",[NSThread currentThread]);  // 打印当前线程
        });
}

GCD 一次性代码(只执行一次):dispatch_once

我们在创建单例、或者有整个程序运行过程中只执行一次的代码时,我们就用到了 GCD 的 dispatch_once 函数。使用
dispatch_once 函数能保证某段代码在程序运行过程中只被执行1次,并且即使在多线程的环境下,dispatch_once也可以保证线程安全。

/**
 * 一次性代码(只执行一次)dispatch_once
 */
- (void)once {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // 只执行1次的代码(这里面默认是线程安全的)
    });
}

GCD 快速迭代方法:dispatch_apply

通常我们会用 for 循环遍历,但是 GCD 给我们提供了快速迭代的函数dispatch_applydispatch_apply按照指定的次数将指定的任务追加到指定的队列中,并等待全部队列执行结束。


GCD 队列组:dispatch_group

有时候我们会有这样的需求:分别异步执行2个耗时任务,然后当2个耗时任务都执行完毕后再回到主线程执行任务。这时候我们可以用到 GCD 的队列组。

调用队列组的 dispatch_group_async 先把任务放到队列中,然后将队列放入队列组中。或者使用队列组的dispatch_group_enterdispatch_group_leave 组合 来实现
dispatch_group_async
调用队列组的 dispatch_group_notify 回到指定线程执行任务。或者使用 dispatch_group_wait 回到当前线程继续向下执行(会阻塞当前线程)。

相关文章

  • iOS多线程-GCD 附带GCD相关代码

    多线程学习笔记-GCD 我把这篇文章所用到的代码总结到这里->GCD项目总结下载地址-GCD-wxk可以下载参考 ...

  • GCD的使用

    最近在学习GCD,所以在网上找了些资料,这里只是对自己学习的总结 1.概念 GCD的好处GCD可用于多核的并行运算...

  • GCD学习总结

    文用来介绍 iOS 多线程中 GCD 的相关知识以及使用方法。通过本文,您将了解到: 1. GCD 简介 2. G...

  • GCD学习总结

    GCD概述: OC: 相关练习: Swift 3.0: 相关练习: 参考资料:http://www.jianshu...

  • GCD学习总结

    GCD GCD的全称是Grand Central Dispatch,字面意思就是“极好的中枢调度器”,它能通过队列...

  • GCD 学习总结

    一、GCD 简介: 全称是 Grand Central Dispatch,是纯 C 语言,提供了非常多强大的函数。...

  • GCD学习总结

    GCD容易混淆的概念 任务,同步,异步 ,串行队列,并发队列 任务就是要做的事情 同步和异步是用来执行任务的 串行...

  • GCD学习总结

    串行同步会造成死锁 执行顺序 :1 5 2 4 3 异步不阻塞线程

  • iOS多线程:『GCD』详尽总结

    iOS多线程:『GCD』详尽总结 iOS多线程:『GCD』详尽总结

  • iOS 多线程学习-思维导图版本

    GCD、NSOperation、NSThread 1.GCD 参考地址:iOS 多线程:『GCD』详尽总结 重要概...

网友评论

      本文标题:GCD学习总结

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