GCD 总结

【iOS】—— 深入了解GCD 百度:Grand Central Dispatch(GCD) 是 Apple 开发的一个多核编程的较新的解决方法。它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统。它是一个在线程池模式的基础上执行的并发任务。在 Mac OS X 10.6 雪豹中首次推出,也可在 iOS 4 及以上版本使用。苹果官方:Grand Central Dispatch(GCD) 是异步执行任务的技术之一。一般将应用程序中记述的线程管理用的代码在系统级实现。... 阅读详情

GCD 总结


通过前面两篇文章和联系,应该学到了多线程和GCD的知识。

但是没有不断的使用和练习,我们永远也不能灵活使用。


这一篇文章就是对GCD的总结,概念是不会出现在文章中。

文章只是简单总结了GCD的一些方法的运用和什么时候运用。


dispatch_async

dispatch_async 是最简单也是最基础的GCD使用

它将开启新的线程来运行block中的代码,并且返回我们需要的值。

例:

[objc]  view plain copy
  1. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // 1    
  2.         UIImage *overlayImage = [self faceOverlayImageFromImage:_image];    
  3.         dispatch_async(dispatch_get_main_queue(), ^{ // 2    
  4.             [self fadeInNewImage:overlayImage]; // 3    
  5.         });    
  6.     });  


使用时间:

1. 自定义串行队列:当你想串行执行后台任务并追踪它时就是一个好选择。这消除了资源争用,因为你知道一次只有一个任务在执行。注意若你需要来自某个方法的数据,你必须内联另一个 Block 来找回它或考虑使用 dispatch_sync。
2. 主队列(串行):这是在一个并发队列上完成任务后更新 UI 的共同选择。要这样做,你将在一个 Block 内部编写另一个 Block 。以及,如果你在主队列调用 dispatch_async 到主队列,你能确保这个新任务将在当前方法完成后的某个时间执行。
3. 并发队列:这是在后台执行非 UI 工作的共同选择。

dispatch_after

dispatch_after 用来延后我们将要进行的操作

例:

[objc]  view plain copy
  1. double delayInSeconds = 1.0;     
  2.     dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); // 1      
  3.     dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ // 2      
  4.         if (!count) {     
  5.             [self.navigationItem setPrompt:@"Add photos with faces to Googlyify them!"];     
  6.         } else {     
  7.             [self.navigationItem setPrompt:nil];     
  8.         }     
  9.     });     


使用时间:

1. 自定义串行队列:在一个自定义串行队列上使用 dispatch_after 要小心。你最好坚持使用主队列。
2. 主队列(串行):是使用 dispatch_after 的好选择;Xcode 提供了一个不错的自动完成模版。
3. 并发队列:在并发队列上使用 dispatch_after 也要小心;你会这样做就比较罕见。还是在主队列做这些操作吧。

dispatch_once() 

dispatch_once()  永远只会运行一次的线程,用来保护线程安全

例:

[objc]  view plain copy
  1. + (instancetype)sharedManager     
  2. {     
  3.     static PhotoManager *sharedPhotoManager = nil;     
  4.     static dispatch_once_t onceToken;     
  5.     dispatch_once(&onceToken, ^{     
  6.         sharedPhotoManager = [[PhotoManager alloc] init];     
  7.         sharedPhotoManager->_photosArray = [NSMutableArray array];     
  8.     });     
  9.     return sharedPhotoManager;     
  10. }     
那,上述例子就是保证单例类在项目中只会实例化一次。

使用须知:

这只是让访问共享实例线程安全。它绝对没有让类本身线程安全。类中可能还有其它竞态条件,例如任何操纵内部数据的情况。这些需要用其它方式来保证线程安全

Dispatch barriers

Dispatch barriers 是一组函数,在并发队列上工作时扮演一个串行式的瓶颈。使用 GCD 的障碍(barrier)API 确保提交的 Block 在那个特定时间上是指定队列上唯一被执行的条目。这就意味着所有的先于调度障碍提交到队列的条目必能在这个 Block 执行前完成。

例:

[objc]  view plain copy
  1. dispatch_barrier_async(self.concurrentPhotoQueue, ^{ // 2      
  2.            [_photosArray addObject:photo]; // 3     
  3.            dispatch_async(dispatch_get_main_queue(), ^{ // 4     
  4.                [self postContentAddedNotification];      
  5.            });     
  6.        });    

dispatch_sync()

dispatch_sync()同步地提交工作并在返回前等待它完成。使用 dispatch_sync 跟踪你的调度障碍工作,或者当你需要等待操作完成后才能使用 Block 处理过的数据。如果你使用第二种情况做事,你将不时看到一个 __block 变量写在 dispatch_sync 范围之外,以便返回时在 dispatch_sync 使用处理过的对象。

例:

[objc]  view plain copy
  1. __block NSArray *array; // 1     
  2.     dispatch_sync(self.concurrentPhotoQueue, ^{ // 2     
  3.         array = [NSArray arrayWithArray:_photosArray]; // 3     
  4.     });     

注意:你需要很小心。想像如果你调用 dispatch_sync 并放在你已运行着的当前队列。这会导致死锁,因为调用会一直等待直到 Block 完成,但 Block 不能完成(它甚至不会开始!),直到当前已经存在的任务完成,而当前任务无法完成!这将迫使你自觉于你正从哪个队列调用——以及你正在传递进入哪个队列。

何时使用:

1. 自定义串行队列:在这个状况下要非常小心!如果你正运行在一个队列并调用 dispatch_sync 放在同一个队列,那你就百分百地创建了一个死锁。
2. 主队列(串行):同上面的理由一样,必须非常小心!这个状况同样有潜在的导致死锁的情况。
3. 并发队列:这才是做同步工作的好选择,不论是通过调度障碍,或者需要等待一个任务完成才能执行进一步处理的情况。


dispatch_sync() 和 dispatch_async() 的区别

dispatch_sync 添加任务到一个队列并等待直到任务完成。dispatch_async 做类似的事情,但不同之处是它不会等待任务的完成,而是立即继续“调用线程”的其它任务。


dispatch_group 

dispatch_group Dispatch Group 会在整个组的任务都完成时通知你。这些任务可以是同步的,也可以是异步的,即便在不同的队列也行。而且在整个组的任务都完成时,Dispatch Group 可以用同步的或者异步的方式通知你。因为要监控的任务在不同队列,那就用一个 dispatch_group_t 的实例来记下这些不同的任务。

例:

[objc]  view plain copy
  1. - (void)downloadPhotosWithCompletionBlock:(BatchPhotoDownloadingCompletionBlock)completionBlock   
  2. {   
  3.     // 1   
  4.     __block NSError *error;   
  5.     dispatch_group_t downloadGroup = dispatch_group_create();    
  6.    
  7.     for (NSInteger i = 0; i < 3; i++) {   
  8.         NSURL *url;   
  9.         switch (i) {   
  10.             case 0:   
  11.                 url = [NSURL URLWithString:kOverlyAttachedGirlfriendURLString];   
  12.                 break;   
  13.             case 1:   
  14.                 url = [NSURL URLWithString:kSuccessKidURLString];   
  15.                 break;   
  16.             case 2:   
  17.                 url = [NSURL URLWithString:kLotsOfFacesURLString];   
  18.                 break;   
  19.             default:   
  20.                 break;   
  21.         }   
  22.    
  23.         dispatch_group_enter(downloadGroup); // 2   
  24.         Photo *photo = [[Photo alloc] initwithURL:url   
  25.                               withCompletionBlock:^(UIImage *image, NSError *_error) {   
  26.                                   if (_error) {   
  27.                                       error = _error;   
  28.                                   }   
  29.                                   dispatch_group_leave(downloadGroup); // 3   
  30.                               }];   
  31.    
  32.         [[PhotoManager sharedManager] addPhoto:photo];   
  33.     }   
  34.    
  35.     dispatch_group_notify(downloadGroup, dispatch_get_main_queue(), ^{ // 4   
  36.         if (completionBlock) {   
  37.             completionBlock(error);   
  38.         }   
  39.     });   
  40. }   


何时使用:

1. 自定义串行队列:它很适合当一组任务完成时发出通知。

2. 主队列(串行):它也很适合这样的情况。但如果你要同步地等待所有工作地完成,那你就不应该使用它,因为你不能阻塞主线程。然而,异步模型是一个很有吸引力的能用于在几个较长任务(例如网络调用)完成后更新 UI 的方式。

3. 并发队列:它也很适合 Dispatch Group 和完成时通知。


dispatch_apply 

dispatch_apply  表现得就像一个 for 循环,但它能并发地执行不同的迭代。这个函数是同步的,所以和普通的 for 循环一样,它只会在所有工作都完成后才会返回。

例:

[objc]  view plain copy
  1. dispatch_apply(3, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(size_t i) {   
  2.    
  3.         NSURL *url;   
  4.         switch (i) {   
  5.             case 0:   
  6.                 url = [NSURL URLWithString:kOverlyAttachedGirlfriendURLString];   
  7.                 break;   
  8.             case 1:   
  9.                 url = [NSURL URLWithString:kSuccessKidURLString];   
  10.                 break;   
  11.             case 2:   
  12.                 url = [NSURL URLWithString:kLotsOfFacesURLString];   
  13.                 break;   
  14.             default:   
  15.                 break;   
  16.         }   
  17.    

何时使用:

1. 自定义串行队列:串行队列会完全抵消 dispatch_apply 的功能;你还不如直接使用普通的 for 循环。

2. 主队列(串行):与上面一样,在串行队列上不适合使用 dispatch_apply 。还是用普通的 for 循环吧。

3. 并发队列:对于并发循环来说是很好选择,特别是当你需要追踪任务的进度时。

 


以上就是对前面三篇文章的一个总结,我将提到的方法都取出来,解释,举例,并简单告知大家该在什么时候使用。

如果你还是不太明白怎么使用,那你还是需要仔细看看前面的文章,然后多联系,多看其他的文章。

GCD详解 什么是GCD? Grand Central Dispatch或者GCD,是一套低层API,提供了一种新的方法来进行并发程序编写。从基本功能上讲,GCD有点像 NSOperationQueue,他们都允许程序将任务切分为多个单一任务然后提交至工作队列来并发地或者串行地执行。GCD比之 NSOpertionQueue更底层更高效,并且它不是Cocoa框架的一部分。 除了代码的平行执行能力, 阅读详情

相关推荐

GCD简析

GCD简单分析

weixin_43661305的博客 1809

CLIP-GCD: Simple Language Guided Generalized Category Discovery(论文翻译)

通用类别发现(Generalized Category Discovery,GCD)需要模型既能对已知类别进行分类,又能对未标记数据中的未知类别进行聚类。之前的方法利用自监督预训练与标记数据的监督微调相结合,然后采用简单的聚类方法。在本文中,我们认为这种方法在处理未知类别的情况下仍然容易出现性能不佳,并且没有充分利用一个关键因素:对象类别之间的语义关系。因此,我们提出了两种互补的多模态(视觉和语言)模型的利用方式。首先,我们通过用CLIP替换单模态特征来建立一个强基线,CLIP受其零样本性能启发。

qq_22583741的博客 1332

机器学习发展历史及现状(重要的期刊,会议,大牛总结)

1 引言 机器学习是指通过计算机学习数据中的内在规律性信息,获得新的经验和知识,以提高计算机的智能性,使计算机能够像人那样去决策。随着各行业对数据的需求量增多,对处理和分析数据的效率要求变高,一系列机器学习算法应运而生。机器学习算法主要是指通过数学及统计方法求解最优化问题的步骤和过程。针对不同的数据和不同模型需求,选择和使用适当的的机器学习算法可以更高效地解决一些实际问题。本文将从机器学习的起源...

Oscar2018的博客 5万+

gcd算法

1.给定两个正整数m,n(m>=n),求它们的最大公约数(一般要求m>=n,若m 具体过程: 1)[求余数],令r=m%n,r为n除m所得余数 2)[余数为0?]若r=0,算法结束,此刻n即为所求答案。否则,继续,转到3。 3)[重置] 置m=n, n=r,返回步骤1) 解释gcd(m,n)算法开头要求m>=n的原因: 举这样一个例子,如m 即m=119, n=544,

suichen1的专栏 1032

伺服电机开发实战指南

伺服电机作为工业自动化的核心部件,正经历前所未有的技术革新。本文从基础原理出发,详细介绍了伺服电机的分类、工作原理和特性,分析了伺服电机系统组成与核心部件,探讨了企业级开发技术,包括控制算法、通信协议和故障诊断等高级功能,并提供了实战案例分析,从行业应用到具体开发步骤,展示了伺服电机的工程实现。通过深入理解伺服电机的原理、掌握开发技术、学习应用案例,可以实现伺服系统的高性能开发与应用。

全栈 1675

C#调用Halcon程序三种方法

C#调用Halcon程序三种方法 1.halcon导出C#文件,在C#里面调用 2.在C#里面使用Halcon引擎调用Halcon程序 3.在C#里面使用Halcon引擎调用.hdev下本地函数或者.hdvp外部函数 Halcon引擎手册:C:/Program Files/MVTec/HALCON-21.11-Progress/doc_en_US/html/manuals/programmers_guide/programmers_guide_0120.html 1.导出C#(代码我只给出类,需要调用)

A541925504的博客 1万+

-XX:+DisableExplicitGC弊端

总结: 如果jvm参数中设置了-XX:+DisableExplicitGC,那么代码中手动调用System.gc()就不会生效。而有些框架中因为是使用的堆外内存,必须手动调用System.gc()来释放。如果禁用掉就会导致堆外内存使用一直增长,造成内存泄露。 详解: 直接内存与System.gc() System.gc()默认会触发一次Full GC,如果在代码中不小心调用了Syst...

pocher的博客 1万+

Kisssoft软件在行星齿轮设计上的初试

行星齿轮传动与链传动相比较,具有质量小,体积小,承载能力强,传动比大,传动效率高等优点,但在行星齿轮传动种种优点下,不可避免的带来一些缺点,对其材料的要求过高,在追求传动比大而体积小的同时,其传动结构大大的复杂化,以及在制造和安装过程中较困难,对于行星齿轮传动设计来说,不仅应该了解其优点,而且应该在设计中,充分发挥其优点,且把其缺点降低到最低的限度。从而才能设计出性能优良的行星齿轮传动装置,为我们赛车提供更加强大的动力保证。 Kisssoft软件为我们行星齿轮传动设计提供了一体化方案,从设...

m0_69808569的博客 1万+

关于GCD的使用(该文章仅作为个人笔记,更多原理资料请查看文章尾部的《相关资料》)

GCD全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 GCD是苹果公司为多核的并行运算提出的解决方案 GCD会自动利用更多的CPU内核(比如双核、四核) GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程) 程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码系统中的每一个进程都有自己独立的虚拟内存空间,而同一个进程的多个线程则共用进程的内存空间。 每创建一个新的线程,

csdn_wangxh的博客 341

国科大《人工智能原理与算法》2021年期末试题+2024经验(2025指南)

2021年期末试题+24年复习指南

MatsumotoChrikk 2925

YOLO26魔改:ICIP2026 SDTA|单深度转置注意力注入C2PSA,长程依赖与局部细节双增强,mAP提升显著

多尺度适配:SDTA的深度卷积与C2PSA的空间注意力结合,增强对多尺度目标的结构感知,改善遮挡与密集场景下的检测鲁棒性。

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 292

iOS——GCD再学习

在异步方法内又同步执行了一个方法,又因为同步执行中的方法执行完成前会阻塞当前线程,因此任务3执行完成前会一直阻塞线程,但是这个同步方法是处于串行队列的,因此要执行任务3要等待任务4执行完,但是任务4又要等任务3执行完才能执行,因此发生了死锁,跟那个主队列+同步执行差不多。syncConcurrent任务在其他线程中执行到追加 任务 1 到主队列中,因为主队列现在没有正在执行的任务,所以,会直接执行主队列的 任务1,等 任务1 执行完毕,再接着执行 任务 2、任务 3。(异步执行 具备开启新线程的能力。

m0_73348697的博客 2243

基于Simulink的占空比调制DTC降低转矩脉动

修改传统SVPWM模块,输入占空比d和有效矢量索引,计算Ton​=d∗Tc​、Toff​=(1−d)∗Tc​,生成对称PWM波形(替代开关表直接输出)。:低速时(n<500rpm)减小dmax​=0.6(避免磁链畸变),高速时(n>2000rpm)增大dmax​=0.8(提升动态响应);kT​/kψ​:转矩/磁链误差增益(需整定,如kT​=0.02/(N⋅m),kψ​=0.1/Wb);(θ为电压矢量与磁链夹角)。② SVM-DTC(占空比计算模块启用,d0​=0.5,kT​=0.02,kψ​=0.1)。

amy_mhd的博客 87

GCD深入学习之GCD的初识

如果移动端访问不佳,可以访问我的个人博客 现在网上关于GCD的介绍已经很多了,在项目中也经常用到,但是没怎么深入研究过,打算写一系列关于GCD使用,参考其他大神写的博客和Apple的技术文档总结一下,一是自己深入学习一下,二是以后忘了可以回过头来温习一下~ 什么是GCD?GCD全名是Grand Central Dispatch(大中央调度器),是系统级的,存在于libdispatch.dylib

W_C__L的博客 7301

从技术债红线到系统治理:透视 SAP Clean Core 中的 Level D

SAP推出的Clean Core分级体系将扩展风险划分为A到D四个等级,其中Level D代表最高风险类别,涉及直接修改标准代码、隐式增强、使用noAPI对象等不被推荐的做法。这些做法虽然短期见效快,但会带来升级冲突、数据完整性风险等长期问题。SAP强调治理重点不是完全消除经典ABAP,而是优先清理Level D对象,逐步向稳定接口迁移。典型案例显示,依赖内部细节的扩展往往在系统升级或云迁移时集中暴露出问题。企业应通过工具链持续监控Level D占比,将其纳入技术债管理范畴。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1063

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

GCD实践——GCD延时执行

这里我将为大家用两种方式来实现延时操作,分别是NSThread和GCD方式。并比较他们的优劣。我把代码放到了Github上面     ,中的GCD02. 【使用NSThread实现延迟】 (1)拖入GCD源码。代码如下: #import "ViewController.h" #import "GCD.h" @interface ViewController () @end @im

乞力马扎罗的雪CYF的博客 3406

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

iOS——【GCD】

GCD指的是Grand Central Dispatch,它是苹果公司开发的一套多线程编程技术。GCD提供了一种简单而有效的方式来管理应用程序中的并发任务。它通过将任务提交到适当的队列(串行队列或并发队列)来管理并发执行的任务,从而帮助开发者更轻松地实现并发编程,提高应用程序的性能和响应速度。上面的就是在后合线程中执行长时间处理,处理结束时,主线程使用该处理结果的源代码。这样,dispatch_async (queue, ^{ 这仅有 一行的代码表示让处理在后台线程中执行。

m0_73348697的博客 1920

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

【iOS】GCD学习

本博客撰写一下小蓝书的GCDGrand Central Dispatch(GCD)是异步执行任务的技术之一。一般将应用程序中记述的线程管理用的代码在系统级中实现。开发者只需要定义想执行的任务并追加到适当的Dispatch Queue中,GCD就能生成必要的线程并计划执行任务。由于线程管理是作为系统的一部分来实现的,因此可统一管理,也可执行任务,这样就比以前的线程更有效率。//让处理在后台线程中执行/**长时间处理*例如AR用画像识别*例如数据库访问*//*

weixin_72437555的博客 1314

GCD简介

1. 什么是GCD GCD,全称是Grand Central Dispatch,它是C语言的API. GCD的核心 : 将block(任务)添加到queue(队列)中. 官方文档的描述: Grand Central Dispatch(GCD)是异步执行任务的技术之一。一般将应用程序中记述的线程管理用的代码在系统级中实现.开发者只需定义想执行的任务并追加到适当的Dispatch Queue中,GCD就能生成必要的线程并执行任务,这样就比以前的线程更有效率. 2.日常使用 dispatch_queu

吃橘子 1万+

GCD定时器(GCD Timer)

时间来不及了,赶快上车… /// 创建一个Timer // /** // dispatch_source创建方法 // // @param type 创建的dispatch_source的类型 // @param handle // @param mask // @param queue 添加到的队列 // @return 返回一个新创...

MeteoriteMan的博客 2533

iOS—GCD详解

文章目录多线程编程进程线程线程与进程的关系多线程编程多线程编程的问题GCD什么是GCDGCD任务和队列GCD的使用步骤队列的创建队列的获取任务的创建方法任务与队列不同组合方式的区别同步执行 + 并发队列异步执行 + 并发队列同步执行 + 串行队列异步执行 + 串行队列同步执行 + 主队列在主线程中调用 同步执行+主队列在其他线程中调用 同步执行+主队列异步执行 + 主队列GCD其他方法GCD栅栏方法:dispatch_barrier_asyncGCD延时执行方法:dispatch_afterGCD 一次性代

qq_45836906的博客 6624

【IOS】GCD学习

笔者近期学习了GCD的使用,对于GCD的认识更加深刻,本篇博客对笔者的学习进行一个小小的总结

2301_79847748的博客 1449

【iOS】 GCD小结

GCD是iOS开发中非常重要的一个内容,笔者今天对于这部分内容做一个介绍,GCD(Grand Central Dispatch)是Apple开发的一个多核编程的较新的解决方法。它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统。它是一个在线程池模式的基础上,执行的并发任务。线程池模式:线程池工作队列已经装满了,且在线程池中正在运行的线程数小于可最大线程数。

qq_73106050的博客 1578

GCD基本使用总结

1.GCD的基本使用 1.1 同步执行 + 串行队列 总结:所有任务都是在主线程完成的,证明了同步执行不具备开启新的线程。所有任务都是按序执行。 1.2 同步执行+并发队列 总结:所有任务都是在主线程中执行的,没有开启新的线程,也就是说同步不具备开启新线程的能力。虽然并发队列可以同时执行多个任务,但是当前只有一个线程,一个线程只能执行一个任务,所以这里也就不存在并发队列。 ...

ivolcano的博客 2251
上一篇: GCD 深入理解(二)
下一篇: iOS使用矢量图的总结
buringHe
博客等级 码龄12年 3粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值