GCD使用

作者: 暖光照 | 来源:发表于2016-10-08 18:10 被阅读0次

名词

  • 串行(Serial)与 并发(Concurrent)
    任务串行,意味着在同一时间,有且只有一个任务被执行,即一个任务执行完毕之后再执行下一个任务。
    任务并发,意味着在同一时间,有多个任务被执行。

  • 同步(Synchronous)与 异步 (Asynchronous)
    同步,意味着在当前线程中执行任务,不具备开启新的线程的能力。

异步,在新的线程中执行任务,具备开启新的线程的能力。

在 GCD 中,这些术语描述当一个函数相对于另一个任务完成,此任务是该函数要求 GCD 执行的。一个同步函数只在完成了它预定的任务后才返回(阻塞当前Queue,先执行传入的Queue)

一个异步函数,刚好相反,会立即返回,预定的任务会完成但不会等它完成。因此,一个异步函数不会阻塞当前线程去执行下一个函数。

GCD获取的队列

//得到运行在主线程的mainQueue
dispatch_queue_t mainQueue=dispatch_get_main_queue();

//得到全局队列(全局的并行队列)
dispatch_queue_t globalQueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//创建一个串行队列
dispatch_queue_t serialQueue=dispatch_queue_create("queueName", DISPATCH_QUEUE_SERIAL);

//创建一个并行队列
dispatch_queue_t concurrentQueue=dispatch_queue_create("queueName", DISPATCH_QUEUE_CONCURRENT);

GCD的使用

基本使用
//同步执行
dispatch_sync(queue, ^{
    // do something
});

//异步执行
dispatch_async(queue, ^{
    // do something
});

// 一次性执行:
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    // do something
});

// 延迟2秒执行:
double seconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, seconds * NSEC_PER_SEC);
dispatch_after(popTime, queue, ^(void){
    // do something
});
使用group
    // 创建group
dispatch_group_t group=dispatch_group_create();
dispatch_group_async(group, queue, ^{
    //任务一
});
dispatch_group_async(group, queue, ^{
    //任务二
});
dispatch_group_notify(group, queue, ^{
    //任务都结束调用
});
单例
 + (Manager *)sharedManager
{
    static Manager *sharedManagerInstance = nil;
    static dispatch_once_t onct;
    dispatch_once(&onct, ^{
    sharedManagerInstance = [[self alloc] init];
    });
    return sharedManagerInstance;
}

串行并行队列与同步异步执行的各种组合

1、 异步函数 + 并行队列
可以新建线程,各线程也是并发执行的。
结论:在队列中的任务“在多个线程并发”执行
2、 同步函数+并发队列
因为是同步函数,所以不新建线程,只要是同步函数,就不会新建线程。
并发队列与否,并不影响同步函数的创建,因为本身就不能多创建线程,也就不存在并发。
结论:在队列中的任务“one by one”执行
3、异步函数+串行队列
这个搭配可以新建线程,但是因为是串行队列,所以实际上也只是开了一条新线程,做完一个,再做另一个。
结论:在队列中的任务“在新线程one by one”执行
4、同步函数+串行队列
这样既不会开新线程,也是串行执行的。
结论:在队列中的任务“one by one”执行

注意:

当串行queue中调用dispatch_sync传入的还是当前queue,会造成死锁。
例如:

 dispatch_async(serialQueue1, ^{
    //serialQueue1队列中调用dispatch_sync传入的还是serialQueue1.
    //dispatch_async创建的新线程会死锁
    dispatch_sync(serialQueue1, ^{
        NSLog(@"1554654-----%@",[NSThread currentThread]);
    });
});           

或:

  //主线程中调用会死锁
   dispatch_sync(dispatch_get_main_queue(), ^{
    NSLog(@"1-----%@",[NSThread currentThread]);
 });

原因:
dispatch_sync会阻塞当前queue等待传入的queue执行完返回才会继续。而传入的还是当前queue。需要执行的block被放到传入queue的队尾等待执行。而queue还在等待dispatch_sync函数返回。block永远不会执行,dispatch_sync永远不会返回,造成死锁

相关文章

  • iOS-多线程:GCD

    GCD 简介 GCD 任务和队列 GCD 的使用步骤 GCD 的基本使用(6种不同组合区别) GCD 线程间的通信...

  • iOS多线程--彻底学会多线程之『GCD』

    GCD 文章目录 GCD简介 任务和队列 GCD的使用步骤 队列的创建方法 任务的创建方法 GCD的基本使用 并行...

  • iOS GCD

    GCD 简介 GCD 任务和队列 GCD 的使用步骤 GCD 的基本使用(六种组合不同区别,队列嵌套情况区别,相互...

  • 多线程之GCD

    GCD介绍 1、GCD简介 2、GCD任务和队列 3、GCD 的基本使用 4、GCD 线程间的通信 5、GCD 的...

  • iOS 关于GCD很详细的描述

    那为什么我们要使用 GCD 呢? 因为使用 GCD 有很多好处啊,具体如下:GCD 可用于多核的并行运算;GCD ...

  • GCD多线程详解

    1. GCD 简介 2. GCD 任务和队列 3. GCD 的使用步骤 4. GCD 的基本使用(6种不同组合区别...

  • iOS多线程--GCD篇

    GCD 文章目录GCD简介任务和队列GCD的使用步骤队列的创建方法任务的创建方法GCD的基本使用并行队列 + 同步...

  • iOS实录16:GCD使用小结(二)

    iOS实录16:GCD使用小结(二) iOS实录16:GCD使用小结(二)

  • iOS GCD的使用

    什么是GCD了解GCD前,需要了解的基础知识GCD的使用使用注意事项 -GCD学习前铺垫-什么是GCDGCD (G...

  • iOS - GCD

    目录 GCD简介 GCD核心概念 GCD队列的使用 GCD的常见面试题 GCD简介 Grand Central D...

网友评论

      本文标题:GCD使用

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