首页 > 其他分享 >[iOS]GCD小结

[iOS]GCD小结

时间:2023-04-30 11:05:12浏览次数:61  
标签:main GCD iOS dispatch queue 任务 线程 执行 小结


Brief Introduction

   GCD,全称Grand Central Dispath,是苹果开发的一种支持并行操作的机制。它的主要部件是一个FIFO队列和一个线程池,前者用来添加任务,后者用来执行任务。

   GCD中的FIFO队列称为dispatch queue,它可以保证先进来的任务先得到执行(但不保证一定先执行结束)。

   通过与线程池的配合,dispatch queue分为下面两种:

  •    Serial Dispatch Queue -- 线程池只提供一个线程用来执行任务,所以后一个任务必须等到前一个任务执行结束才能开始。
  •    Concurrent Dispatch Queue -- 线程池提供多个线程来执行任务,所以可以按序启动多个任务并发执行。

1. Basic Management

   我们可以通过dispatch_queue_cretae来创建队列,然后用dispatch_release释放。比如下面两段代码分别创建串行队列和并行队列:





1. serialQ = dispatch_queue_create("eg.gcd.SerialQueue", DISPATCH_QUEUE_SERIAL);  
2. ^{  
3.    // Code here 
4.  
5.  
6.  
7. concurrentQ = dispatch_queue_create("eg.gcd.ConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);  
8. ^{  
9.    // Code here 
10.  
11.


   而系统默认就有一个串行队列main_queue和并行队列global_queue:






1. globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  
2. mainQ = dispatch_get_main_queue();


   通常,我们可以在global_queue中做一些long-running的任务,完成后在main_queue中更新UI,避免UI阻塞,无法响应用户操作:







1. 0), ^{  
2.    // long-running task 
3.    dispatch_async(dispatch_get_main_queue(), ^{  
4.        // update UI 
5.    });  
6.




   上面提到dispatch_async这个接口,用来提交blcok给指定queue进行异步执行。这个接口会在成功提交block后立即返回,然后继续执行下去。由于block是定义在栈上的,所以需要将其复制到堆上,见这里。



   与之相对应的是dispatch_sync接口,提交block以供同步执行。这个接口会等到block执行结束才返回,所以不需要复制block。So,如果在调用该接口在当前queue上指派任务,就会导致deadlock。维基百科上给了段示例代码:





1. exampleQueue = dispatch_queue_create("com.example.unique.identifier", NULL );  
2. exampleQueue,^{  
3.  dispatch_sync( exampleQueue,^{  
4.    printf("I am now deadlocked...\n");  
5.  });});  
6. exampleQueue );

   如果追求的是并发,那么dispatch_sync有什么用呢?关于dispatch_sync的用途,SO上有 讨论



   

2. Normal Control

  • dispatch_once

   如果没有记错的话,在iOS Con 2012上,大众点评的同学分享了个Topic叫《iOS开发最佳实践》,开篇讲singleton实现的演进(怎么演进都有可以挑的刺),后面转折说要把精力放到用户看得到的地方。

   如果把singleton和best practice放在一起,那么我很容易联想到dispatch_once这个函数,它可以保证整个应用程序生命周期中某段代码只被执行一次





1. staticdispatch_once_t onceToken;  
2. ^{  
3.    // code to be executed once 
4.



  • dispatch_after

   有时候我们需要等个几秒钟然后做个动画或者给个提示,这时候可以用dispatch_after这个函数:





1. doubledelayInSeconds = 2.0;  
2. popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);  
3. dispatch_get_main_queue(), ^(void){  
4.    // code to be executed on the main queue after delay 
5.



  • dispatch_set_target_queue

   通过dispatch_set_target_queue函数可以设置一个dispatch queue的优先级,或者指定一个dispatch source相应的事件处理提交到哪个queue上。





1. globalQ);




  • dispatch_apply

   执行某个代码片段若干次。




1. globalQ, ^(size_tindex) {  
2.    // do sth. 10 times 
3.



  • dispatch group

   Dispatch Group机制允许我们监听一组任务是否完成:





1. group = dispatch_group_create();  
2. concurrentQ, blk0);  
3. concurrentQ, blk1);  
4. concurrentQ, blk2);  
5. mainQ, ^{  
6.    // update UI 
7.  
8.



   或者说同步地等待一段时间看是否结束:




1. time = dispatch_time(DISPATCH_TIME_NOW, 1ull * NSEC_PER_SEC);  
2. time);



  • dispatch_barrier_async

   通过dispatch_barrier_async函数提交的任务会等它前面的任务执行结束才开始,然后它后面的任务必须等它执行完毕才能开始。




1. blk0);  
2. blk1);  
3. blk_barrier);  
4. blk2);


这份官方文档很清晰地按功能为GCD相关函数进行了分类。

Jason Lee @ Hangzhou


标签:main,GCD,iOS,dispatch,queue,任务,线程,执行,小结
From: https://blog.51cto.com/u_548275/6237788

相关文章

  • IOS实例变量和属性
    在IOS编程中,很多人没有理解实例变量与属性的区别,我根据自己的经验,这这里与大家分享下这里面的区别,下面我写一个简单的例子:.h@interfaceMyController:UIViewController{UILabel*_myLabel;//这里是实例变量声明}@property(nonatomic,retain)UILabel*myLabe......
  • iOS开发 UItableView中的单元…
    iOSiPhone开发UItableView中的单元格背景渐变渐变如果用背景图片,会让你的app臃肿。给APP瘦身,我们可以使用代码来解决渐变的问题。这篇文章是解决表格中的单元格的简便问题,同时解决单元格外边框问题。1:设置好开始颜色与结束颜色。推荐一个小工具,在chrome浏览器上安装一个扩展......
  • iOS数据存储的四种方案对比
    你是用什么方法来持久保存数据的?这是在几乎每一次关于iOS技术的交流或讨论都会被提到的问题,而且大家对这个问题的热情持续高涨。本文主要从概念上把“数据存储”这个问题进行剖析,并且结合各自特点和适用场景给大家提供一个选择的思路,并不详细介绍某一种方式的技术细节。谈到数据......
  • iOS开发UITableView基本使用方法总…
    UITableView基本使用方法1.首先,Controller需要实现两个delegate,分别是UITableViewDelegate和UITableViewDataSource2.然后UITableView对象的delegate要设置为self。3.然后就可以实现这些delegate的一些方法拉。(1)-(NSInteger)numberOfSectionsInTableView:(UITableView*......
  • Vue 异步通信Axios
    使用Axios实现异步通信需要先导入cdn:<scriptsrc="https://unpkg.com/[email protected]/dist/axios.min.js"></script>使用到的数据data.json{"name":"kuang","url":"https://www.bilibili.com/?spm_id_from=333.788.0......
  • JavaWeb回顾与小结(五)
    Mybatis基础操作环境准备工作准备数据库表创建一个新的springboot工程,选择引入对应的起步依赖(mybatis,mysql驱动,lombok)application.properties中引入数据库连接信息创建对应的实体类Emp(实体类属性采用驼峰命名)准备Mapper接口EmpMapper根据主键删除SQL语句delete......
  • JavaWeb回顾与小结(四)
    数据库操作-DQLDQL英文全称是DataQueryLanguage(数据查询语言),用来查询数据库表中的记录基本查询条件查询where分组查询groupby排序查询orderby分页查询limit基本查询语法查询多个字段select字段1,字段2,字段3from表名;查询所有字段(通配符)select*from......
  • dell 7080m black mac bios setup
    BISO设置参考的以下帖子,改了一部分内容USBWakeSupport和WakeonLAN/WLAN保持了默认,因为我用不到网络唤醒功能。​https://github.com/3dudu/dell-optiplex-7080-hackintosh-opencore设置项   值SATAOperation   AHCIIntegratedNIC   EnabledSecureBootEnable ......
  • (2023)iOS17开放侧载的网友观点调研
    前言因为欧盟方面的强制措施,不出意外的话,iOS17开始苹果将被迫开放侧载。虽然具体如何开放的细节还不确定,但是这毕竟对苹果,开发者,以及用户都是不小的事情。整理了下网友们(主要是开发者们),对侧载的一系列看法和猜测。因为很多意见是相左的,所以整理成了反面观点和正面观点。反面......
  • Chrome Kiosk Mode All In One
    ChromeKioskModeAllInOneChrome信息亭KioskMode使浏览器隐藏边框来全屏展示WebApp页面,一般用于商场超市、快餐店等大屏自助点餐场景demoshttps://www.bilibili.com/video/BV1UK4y147uh/?t=146(......