通俗易懂GCD

作者: 飞翔的小骑兵 | 来源:发表于2015-07-31 15:43 被阅读983次
IOS三人行IOS三人行

Dispatch Queue(调度队列)

Serial Dispatch Queue串行代码;
Concurrent Dispatch Queue并行代码。

创建队列:

  1. 创建Serial Dispatch Queue。

dispatch_queue_t serialQueue =
dispatch_queue_create(“com.SerialQueue”, NULL);

  1. 创建Concurrent Dispatch Queue
dispatch_queue_t concurrentQueue =
  dispatch_queue_create(“com.ConcurrentQueue”,
    DISPATCH_QUEUE_CONCURRENT);

对于串行队列,每创建一个串行队列,系统就会对应创建一个线程,同时这些线程都是并行执行的,只是在串行队列中的任务是串行执行的。大量的创建串行队列会导致大量消耗内存,这是不可取的做法。串行队列的优势在于他是一个线程,所以在操作一个全局数据时候是线程安全的。当想并行执行而不发生数据竞争时候可以用并行队列操作

Main&Global Dispatch Queue

Main Dispatch Queue是在主线程中执行任务的Dispatch Queue。因为主线程只有1个,所以Main Dispatch Queue是Serial Dispatch Queue。追加到Main Dispatch Queue中的任务将在主线程的RunLoop中执行。因为是在主线程中执行,所以应该只将用户界面更新等一些必须在主线程中执行的任务追加到Main Dispatch Queue中。

dispatch_queue_t dispatch_main_queue = dispatch_get_main_queue();

global Dispatch Queue是所有应用程序都能使用的Concurrent Dispatch Queue。大多数情况下,可以不必通过dispatch_queue_create函数生成Concurrent Dispatch Queue,而是只要获取Global Dispatch Queue使用即可。Global Dispatch Queue有4个优先级,分别是:High、Default、Low、Background。

dispatch_queue_t dispatch_global_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_group

如果想在dispatch_queue中所有的任务执行完成后在做某种操作,在串行队列中,可以把该操作放到最后一个任务执行完成后继续,但是在并行队列中怎么做呢。这就有dispatch_group 成组操作。比如

    dispatch_queue_t dispatchQueue = dispatch_queue_create("ted.queue.next", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t dispatchGroup = dispatch_group_create();
    dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
        NSLog(@"dispatch-1");
    });
    dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
        NSLog(@"dspatch-2");
    });
    dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
        NSLog(@"end");
    });

上面的 log1 和log2输出顺序不定,因为是在并行队列上执行,当并行队列全部执行完成后,最后到main队列上执行一个操作,保证“end”是最后输出。 另外,这里也可以不用创建自己的并行队列,用全局的global,那个也是个并行队列. dispatch_get_gloable_queue(0,0);

dispatch_barrier_async

 dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", 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_barrier_async 作用是在并行队列中,等待前面两个操作并行操作完成,这里是并行输出
dispatch-1,dispatch-2
然后执行
dispatch_barrier_async中的操作,(现在就只会执行这一个操作)执行完成后,即输出
"dispatch-barrier,
最后该并行队列恢复原有执行状态,继续并行执行
dispatch-3,dispatch-4

dispatch_async 和dispatch_sync

dispatch_sync(),同步添加操作。他是等待添加进队列里面的操作完成之后再继续执行。

    dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT);
    NSLog(@"1");
    dispatch_sync(concurrentQueue, ^(){
        NSLog(@"2");
        [NSThread sleepForTimeInterval:10];
        NSLog(@"3");
    });
    NSLog(@"4");

输出 :

11:36:25.313 GCDSeTest[544:303] 1

11:36:25.313 GCDSeTest[544:303] 2

11:36:30.313 GCDSeTest[544:303] 3//模拟长时间操作

11:36:30.314 GCDSeTest[544:303] 4

dispatch_async ,异步添加进任务队列,它不会做任何等待

    dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT);
    NSLog(@"1");
    dispatch_async(concurrentQueue, ^(){
        NSLog(@"2");
        [NSThread sleepForTimeInterval:5];
        NSLog(@"3");
    });
    NSLog(@"4");

输出:

11:42:43.820 GCDSeTest[568:303] 1

11:42:43.820 GCDSeTest[568:303] 4

11:42:43.820 GCDSeTest[568:1003] 2

11:42:48.821 GCDSeTest[568:1003] 3//模拟长时间操作时间

dispatch_after

dispatch_after能让我们添加进队列的任务延时执行,比如想让一个Block在10秒后执行:

var time = dispatch_time(DISPATCH_TIME_NOW, (Int64)(10 * NSEC_PER_SEC))

dispatch_after(time, globalQueue) { () -> Void in

    println("在10秒后执行")

} 

需要注意的是,使用dispatch_after实现延迟执行某动作,时间并不是很精确,实际上是过多久将Block追加到main Queue中,而不是执行该动作,如果此时main queue中的任务很多,没有执行完毕,那么新添加的这个动作就要继续推迟

相关文章

  • 通俗易懂GCD

    Dispatch Queue(调度队列) Serial Dispatch Queue串行代码;Concurrent...

  • iOS GCD的形象解释

    本文力求做到全网将GCD队列和任务各种组合讲得最通俗易懂的文章,如果做不到,那你们来打我啊!文章参考内容:iOS ...

  • 多线程之GCD

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

  • 扩展GCD(求逆元,解同余方程等等)

    首先要知道gcd函数的基本性质:gcd(a,b)=gcd(b,a)=gcd(|a|,|b|)=gcd(b,a%b)...

  • iOS - GCD

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

  • iOS-多线程:GCD

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

  • 浅析GCD

    GCD目录: 1. GCD简介 为什么要用GCD呢? GCD可用于多核的并行运算GCD会自动利用更多的CPU内核(...

  • 7.3 多线程-GCD

    多线程-GCD 多线程-GCD-串行并行 多线程-GCD.png GCD-线程的通讯、延时操作、定时器 GCD-线...

  • iOS 多线程--GCD

    一、GCD基本介绍 1.GCD简介 GCD是Grand Central Dispatch的缩写,GCD是苹果推出的...

  • 自用算法模板(JAVA版)

    一、数论 1)GCD GCD(求最大公约数) QGCD(快速GCD) extGCD(拓展GCD,解决ax + by...

网友评论

    本文标题:通俗易懂GCD

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