美文网首页
GCD学习小结

GCD学习小结

作者: 凸阿滨 | 来源:发表于2017-04-26 11:08 被阅读4次

一)简介

Serial Dispatch Queue要求等待正在执行的任务完成,再执行下一个。而Concurrent Dispatch Queue中后面的任务可以不必等待正在执行的任务执行完成就可以开始执行,也就是同时可以执行多个任务。换句话说,其实就是Serial Dispatch Queue只会创建一个线程来执行任务,而Concurrent Dispatch Queue会创建多个线程同时执行多个任务。

名词定义:Serial Dispatch Queue串行代码;Concurrent Dispatch Queue并行代码。

(二)队列创建

1 串形队列创建

dispatch_queue_t serialQueue =

dispatch_queue_create("com.SerialQueue" ,NULL);

2 并形队列创建

dispatch_queue_t concurrentQueue =

dispatch_queue_create("com.ConcurrentQueue",

DISPATCH_QUEUE_CONCURRENT);

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

dispatch_queue_t concurrentQueue =dispatch_queue_create("my.concurrent.queue",DISPATCH_QUEUE_CONCURRENT);

NSLog(@"1");

dispatch_sync(concurrentQueue, ^(){

NSLog(@"2");

[NSThreadsleepForTimeInterval:10];

NSLog(@"3");

});

NSLog(@"4");

输出:1234

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

dispatch_queue_t concurrentQueue =dispatch_queue_create("my.concurrent.queue",DISPATCH_QUEUE_CONCURRENT);

NSLog(@"1");

dispatch_async(concurrentQueue, ^(){

NSLog(@"2");

[NSThreadsleepForTimeInterval:5];

NSLog(@"3");

});

NSLog(@"4");

输出:1423

Concurrent Dispatch Queue不过创建多少都没有问题,因为Concurrent Dispatch Queue所使用的线程由系统的XNU内核高效管理,不会影响系统性能。

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

(三)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

1:实现

如果想在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);

2:实现

以上方法有一个问题就是在任务1没有执行完回调之后就认为任务全部处理完成执行输出“end”

dispatch_group_t group =dispatch_group_create();

dispatch_group_enter(group);

// 任务代码1

dispatch_group_leave(group);

// 回调执行1

dispatch_group_enter(group);

// 任务代码2

dispatch_group_leave(group);

// 回调执行2

dispatch_group_notify(group,dispatch_get_main_queue(), ^{

// 主线程处理 全部完成

});

在任务开始前 调用 enter,任务完成时调用leave,直到它发现group里面的任务全部leave(也就是所有任务的回调都执行完成后),它才放弃阻塞(任务全部完成),然后我们在主线程更新UI告知用户.

(五)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

相关文章

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

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

  • GCD 学习小结

    概念 串行队列、并行队列 串行队列,是指同一时间内,队列内只有一个任务在执行。 并行队列,是指同一时间内,队列内有...

  • GCD学习小结

    一)简介 Serial Dispatch Queue要求等待正在执行的任务完成,再执行下一个。而Concurren...

  • GCD线程学习小结

    GCD的三种队列类型 GCD的核心是dispatch队列。dispatch Block的执行最终会放到某个队列中去...

  • GCD 组队列学习小结

    使用场景:网络下载图片,全部图片下载完成后 加载到界面 创建组队列,创建全局队列,回去住队列 将异步任务添加到全局...

  • gcd小结

    DCD 其他用法

  • GCD小结

    GCD 全称: Grand Central Dispatch本质: 一套低层级的 C 语言 API,GCD 管理着...

  • GCD 小结

    一、 同步/异步、串行/并行的区别 1.同步/异步 同步/异步是指线程与线程之间的关系. 2.串行/并行 串行/并...

  • GCD小结

    本文总结于 一些 iOS / Web 开发相关的翻译或原创博客文章 GCD (grand_central_disp...

  • GCD学习(三)

    GCD学习一 GCD学习二 GCD学习三 常用函数: dispatch_set_target_queue disp...

网友评论

      本文标题:GCD学习小结

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