iOS中GCD线程开发入门

【iOS】多线程问题总结--GCD 在 iOS 开发过程中,我们一般在主线程里边进行 UI 刷新,例如:点击、滚动、拖拽等事件。我们通常把一些耗时的操作放在其他线程,比如说图片下载、文件上传等耗时操作。而当我们有时候在其他线程完成了耗时操作时,需要回到主线程,那么就用到了线程之间的通讯。 阅读详情

当处理一些复杂且耗时的任务时,因为任务需要花费比较长的时间,如果是在主线程执行这些任务,有可能会造成造作卡顿,不流畅。所以把一些耗时的任务放到别的线程中会好一点。
但是开线程也是有代价的,不要随便乱开线程。只在需要的时候使用。
先来介绍一些概念性的东西,对使用GCD会有帮助。

串行,并发

串行(serial):一次只能执行一个任务。
并发(concurrent):同意时间可以有多个任务被执行。
就好比去银行办理业务,如果只开了一个窗口,那么一段时间能只能有一个客户办理业务,这就是串行。如果银行同事开了多个窗口,那么就可以有多个人同时办理业务,这就是并发。

临界区

一段代码不能被并发执行,两个线程不能同时执行这段代码。

上下文切换

当单个进程切换执行不同线程时存储与恢复执行状态的过程,在编写多任务应用时很普遍,但是会带来一些额外的开销。

线程安全 Thread safe

线程安全的代码能在多线程或者并发任务中被安全的调用,而不会导致任何问题。线程不安全的代码在某个时刻只能在一个上下文中运行。举个例子,NSArray,因为只能读取,所以可以在多个线程中同时使用。NSMutableArray就不是线程安全的,如果在读取的过程中,另一个线程刚好添加了一个对象到数组里,那么也许读取的结果就会出错。

队列 queue

dispatch_queue 使用FIFO(first in first out:先入先出)的顺序来执行这些任务,保证了第一个开始的任务就是第一个被添加到队列里的任务

main_queue :主队列,主队列是唯一可用于刷新UI的线程,这个队列就是用于发生消息给UIView,发送通知的。

global_queue:有4个不同的优先级:background,low,default,high。苹果的API也会使用这个队列,所以你添加的任务可能不会马上被执行。

  • 开启一个线程
//dispatch_async(<#dispatch_queue_t queue#>, <#^(void)block#>)
//第一个参数 获取队列:全局队列 或者主线程队列
//第二个参数 要执行的Block代码

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        self.view.backgroundColor =
        [UIColor redColor];
        [self qwert];

        dispatch_async(dispatch_get_main_queue(), ^{
        //在主线程中更新UI
            self.imageView.image = [UIImage imageNamed:@"2.jpg"];
        });
    });

    //异步的执行一个全局队列global_queueu

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

  • 延后工作 dispatch_after
//   设定一个时间基数
    double delayInSecond = 4.0;
//声明一个变量指定要延迟的时长 "NSEC_PER_SEC "
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSecond*NSEC_PER_SEC);
//等待popTime 的时间 然后异步的添加一个block到主线程
    dispatch_after(popTime, dispatch_get_main_queue(), ^{
        self.imageView.image = [UIImage imageNamed:@"2.jpg"];

    });

dispatch_after:是一个延迟的dispatch_async,在等待了一段时间后才开始执行。

最好只在主队列使用。其它的队列不推荐使用。

  • 创建一个线程安全的单例

单例常常是不安全的,一般的创建方法

+(instancetype)shareManger{
    static PhotoManager *sharedPhotoManager = nil;
    if (!sharedPhotoManager) {
        sharedPhotoManager = [[PhotoManager alloc] init];
        sharedPhotoManager.photosArray = [NSMutableArray array];
        NSLog(@"初始化了");
    }
    return sharedPhotoManager;
}
//有可能淡第一个线程进入IF语句的时候 ,这时候正好第二个线程启动了,完成了这个单例的初始化,这时切换回了第一个线程,又初始化了一次。那就又两个单例了。
+(instancetype)shareManager{
    static test *test1 = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        test1 = [[test alloc]init];      
    });
    return test1;
}

dispatch_once() 整个APP生命周期里只执行一次,这样写碰到上面的情况就不会再出现两个单例的情况了,因为第二个线程会被阻塞。。

有可能同时进行读写功能的时候,当一个线程在读数组,一个线程在写数组的时候,有可能出现线程安全问题
比如:

//读数组
- (NSArray *)photos
{
    return _photosArray;
}
//写数组
- (void)addPhoto:(Photo *)photo
{
    if (photo) {
        [_photosArray addObject:photo];
    }
}

以上就是线程不安全的。

障碍
dispatch_barriers :是一组函数,使GCD的障碍API确保提交的Block在那个特定时间上是制定队列上唯一执行的条目,这就意味着所有的咸鱼调度障碍提交到队列的条目必能在这个Block执行前完成,同一时间只能执行一个障碍Block,障碍Block完成后就可以去执行其他的Block
最好在自定义并发队列中执行,这对于原子或者临界区代码来说都是极佳的选择,任何你在设置货实例化的需要线程安全的事物都是使用障碍的最佳候选。

可以建立一个属性 :
@property (nonatomic, strong) dispatch_queue_t concurrentPhotoQueue;
然后再单例中创建你的自定义队列

//初始化自定义队列
    self.concurrentPhotoQueue = dispatch_queue_create("我是concurrentPhotoQueue自定义队列", DISPATCH_QUEUE_CONCURRENT);
//  这里使用 dispatch_queue_create 初始化 concurrentPhotoQueue 为一个并发队列。第一个参数是样式命名;确保它是描述性的,将有助于调试。第二个参数指定你的队列是串行还是并发 

然后是写入数组的代码

- (void)addPhoto:(Photo *)photo
{
    if (photo) {
//添加写操作到自定义队列,当稍后执行时,这将是队列中唯一执行的条目。这个Block永远不会同时和其他Block一起在队列中执行。
dispatch_barrier_async(self.concurrentPhotoQueue, ^{
            [_photosArray addObject:photo];
            dispatch_async(dispatch_get_main_queue(), ^{
//发送一个通知说明完成了添加图片,因为会刷新UI,所以用主线程
                [self postContentAddedNotification];
            });
        });
    }
}

写操作完成了,但是还有读擦偶偶,要确保线程安全,你需要在自定义队列上执行操作,dispatch_sync()同步的提交工作并且在返回前等待它完成(或者你需要等待操作完成后才能使用Block处理过的数据(同事写一个__blcok变量写在dispatch_sync范围之外,来使用dispatch_sync处理过的对象))

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

- (NSArray *)photos
{
    __block NSArray *array ;
    dispatch_sync(self.concurrentPhotoQueue, ^{
        array = [NSArray arrayWithArray:_photosArray];

    });
    return array;
}

未完待续。。。

深入理解iOS GCD多线程开发 htmltable {th, td {th {pre {简介:本文深入探讨了iOS GCD的多线程开发,包括其核心概念、任务提交方式、主队列的特性、其他高级特性以及在实际开发中的应用。GCD是Apple的多线程解决方案,支持串行和并行队列,并提供全局队列、栅栏、延时执行和一次性执行等特性。开发者能够通过GCD高效管理并发任务,提升应用性能和响应速度,同时避免竞态条件和资源泄漏等问题。 阅读详情

相关推荐

深入掌握iOS GCD多线程编程

本文还有配套的精品资源,点击获取 简介:GCD(Grand Central Dispatch)是iOS多线程编程的高效工具,简化了并发编程的复杂性,提供了灵活的异步执行机制。本教程详细介绍了GCD的基本概念、队列类型、任务提交方式以及工作模式,并通过示例讲解了如何创建队列、提交任务、延迟执行、实现栅栏任务以及使用小组件来跟踪任务。同时,提供了GCD最佳实践建议,如避免主线程...

weixin_42601608的博客 1008

iOS多线程开发之GCD 用法入门

我们知道,在iOS中进行多线程编程,主要有三种方式:【NSThread】、【NSOperation】和【GCD】。其中又以【GCD】为苹果官方最为推荐。本文将利用一个简单的demo,简述GCD的用法入门,以及本人对GCD的一点肤浅理解和学习心得。 先把参考文章列出: http://www.cnblogs.com/kenshincui/p/3983982.html http://ww...

weixin_30895603的博客 115

iOS多线程开发实战:GCD异步任务与线程锁详解

许多应用维护着全局可变状态(如用户配置、缓存索引等),这些状态若被多线程并发修改,极易引发数据错乱。使用串行队列可实现“队列绑定(queue affinity)”模式,即将状态访问限定在一个特定队列上执行,从而天然保证线程安全。@endNSLog(@"写入: %@ = %@", key, value);});});@end。

weixin_34268462的博客 1025

iOS开发多线程篇—GCD的基本使用

iOS开发多线程篇—GCD的基本使用 一、主队列介绍 主队列:是和主线程相关联的队列,主队列是GCD自带的一种特殊的串行队列,放在主队列中得任务,都会放到主线程中执行。 提示:如果把任务放到主队列中进行处理,那么不论处理函数是异步的还是同步的都不会开启新的线程。 获取主队列的方式:  dispatch_queue_t queue=dispatch_get_ma

为你超神 507

子图同构之乌尔曼算法Ullmann Algorithm的python实现

给定两个图Ga​(子图)和Gb​(原图),其中Ga​有pa​个点和qa​条边,Gb​有pb​个点和qb​条边,其邻接矩阵分别为A和B。子图同构的关键在于找到一种从Ga​的点到Gb​的点的映射MM是一个pa​行pb​列的矩阵,且满足每行只有一个1(表示Ga​中的一个点唯一地映射到Gb​中的一个点),每列至多一个1(确保Gb​中的点不会被重复映射)。定义Ccij​MMBT,若在图Ga​。

weixin_42822813的博客 1974

别再为PT100测温发愁了!手把手教你用ADS1247+STM32搞定高精度温度采集(附完整代码)

本文详细介绍了如何使用ADS1247与STM32构建高精度PT100测温系统,涵盖硬件设计、SPI配置、温度计算及调试技巧。通过24位ADC和内置PGA,实现0.1℃级精度,适用于工业自动化和医疗设备。附完整代码和常见问题解决方案,助你快速掌握高精度温度采集技术。

weixin_42524703的博客 344

iOS移动开发多线程—GCD介绍

iOS开发多线程篇—GCD介绍 一、简单介绍 1.什么是GCD? 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数   2.GCD的优势 GCD是苹果公司为多核的并行运算提出的解决方案 GCD会自动利用更多的CPU内核(比如双核、四核) GCD会自动管理线程的生命周期(创建线程

Demon_JiAo的博客 472

FICO F.27 Customer statement 打印

需求,定制化打印,替换标准的F.27打印 类似于采购订单的打印,但是略有不同,查阅资料之后步骤如下: T-code F.27 is SAP standard program to produce customer/vendor correspondence (letter). Correspondence Type is used to specify the related printing program and form for the particular correspondence. SAP

IamRunjiang的博客 1965

iOS开发多线程篇—GCD介绍

iOS开发多线程篇—GCD介绍 一、简单介绍 1.什么是GCD? 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数   2.GCD的优势 GCD是苹果公司为多核的并行运算提出的解决方案 GCD会自动利用更多的CPU内核(比如双核、四核) GCD会自动管理线程的生命周期(创建线程、调

dj_liu的博客 693

电磁仿真新手必看:如何用CST Studio Suite 2023完成第一个PCB辐射仿真?

本文详细解析了如何使用CST Studio Suite 2023进行PCB辐射仿真,适合电磁仿真新手快速上手。从工程准备、求解器配置到端口设置和后处理技巧,全面覆盖三维全波电磁场仿真软件的核心操作步骤,帮助工程师精准预测和解决PCB电磁辐射问题。

y7z8a9的博客 733

ADS Layout设计实战:从参数设置到协同仿真

本文详细介绍了ADS Layout设计的完整实战流程,从新建工程、单位设置、个性化偏好配置等基础操作入手,逐步深入到基板参数配置、端口设置与电磁仿真器选择等核心环节。重点阐述了参数化版图设计与扫描优化、以及原理图与Layout协同仿真的高级技巧,并通过一个微带线低通滤波器设计案例,完整演示了从理论到实现的闭环设计方法,帮助工程师高效、准确地完成高频电路版图设计与验证。

weixin_29268637的博客 797

IOS开发多线程篇—GCD介绍

iOS开发多线程篇—GCD介绍 一、简单介绍 1.什么是GCD? 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数   2.GCD的优势 GCD是苹果公司为多核的并行运算提出的解决方案 GCD会自动利用更多的CPU内核(比如双核、四核) GCD会自动管理线程的生命周期(创建线程、调

阿赫の宅 193

ComfyUI报错ModuleNotFoundError: No module named ‘comfy.options‘

好家伙,我一想我刚刚好像用了pip安装了comfy模块,不会是和ComfyUI自带的comfy模块产生冲突了吧。(3)还有的说是项目不是最新版,叫更新到最新版本的,好家伙,我报错之前根本没更新也没错,突然就报错的。(4)还有的说没有comfy.options这部分代码,叫自己去拉一个,我一看也有啊。我也不知道啥时候脑抽风去装这么个东西的,幸好我聪明机智,一眼就知道了。看把我气的,然后网上搜集各种资料,一个一个去试。

满目星辰 5157

iOS面试:4.多线程GCD

进程是指在系统中正在运行的一个应用程序。对于电脑而已,你打开一个软件,就相当于开启了一个进程。对于手机而已,你打开了一个APP,就相当于开启了一个进程。线程是进程的基本执行单位。一个进程中至少会有一条线程,当然也可能会有多条线程。比如你使用QQ音乐听歌,系统会创建一条线程去播放音乐。使用QQ音乐下载歌曲,系统会创建一条线程去下载歌曲。这两个操作是可以同时进行的,也就说一个进程中可以同时运行多条线程。

长沙火山 3062

芯片ATE测试PAT(Part Average Testing)学习总结-20250916

文章摘要:零件平均测试(PAT)是半导体制造中基于统计学的质量控制方法,分为静态和动态两种类型。静态PAT通过预先设定的固定限值(每6-8批次更新)筛选异常芯片,计算采用稳健平均值和四分位间距。动态PAT则根据实时数据调整限值,能更精确识别异常而不误判合格芯片。两种方法均采用"均值±6倍标准差"的计算公式,但动态PAT具有更好的适应性和准确性。该方法通过统计分析提高了芯片产品的质量和可靠性。

歌颂苦难的行为是无耻的; 1190

一文看懂 SAP Integration Suite:从架构治理、接口编排到事件驱动的集成全景

SAP Integration Suite是企业数字化转型中的关键集成平台,通过统一的方法论和工具链解决系统互联、数据对齐和流程协同等复杂问题。其核心能力包括:1)集成评估(Integration Assessment)提供战略规划框架;2)迁移评估(Migration Assessment)支持从传统平台向云的平滑过渡;3)云集成(Cloud Integration)实现日常业务流程编排;4)集成顾问(Integration Advisor)简化B2B标准映射;5)贸易伙伴管理(TPM)优化外部协作流程;

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

iOS——GCD再学习

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

m0_73348697的博客 2243

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

ios开发进阶之多线程01 线程 GCD

一 多线程基础 什么是进程?进程是指在系统中正在运行的一个应用程序。 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内。 什么是线程?1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程)。 1个线程中任务的执行是串行的(执行完上一个才能执行下一个)。 什么是多线程?1个进程中可以开启多条线程,多条线程可以并行(同时)执行不同的任务。 线程可以并行, 但是每个线程中的任务还

IOS开发进阶之路 653

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

iOS——【GCD】

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

m0_73348697的博客 1921

visio安装包

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

【iOS】GCD学习

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

weixin_72437555的博客 1314

iOS - 多线程-GCD

GNUstep是GNU计划的项目之一,它将Cocoa的OC库重新开源实现了一遍。虽然GNUstep不是苹果官方源码,但还是具有一定的参考价值。队列(Concurrent Dispatch Queue)看似是在没有延迟的情况下执行,实际上因为该方法是基于。队列(Serial Dispatch Queue)添加一个定时器,但是因为此时我们是在。这时候都有打印,只不过打印顺序。主要影响:能不能开启新的线程。主要影响:任务的执行方式。上面的例子中,主要是考察。,这次打印顺序是正常的。

sharp521的博客 1231

iOS开发之多线程技术(NSThread、OperationQueue、GCD)

在前面的博客中如果用到了异步请求的话,也是用到的第三方的东西,没有正儿八经的用过iOS中多线程的东西。其实多线程的东西还是蛮重要的,如果对于之前学过操作系统的小伙伴来说,理解多线程的东西还是比较容易的,今天就做一个小的demo来详细的了解一下iOS中的多线程的东西。可能下面的东西会比较枯燥,但还是比较实用的。   多线程用的还是比较多的,废话少说了,下面的两张截图是今天我们实验的最终结果,应

风的坚持 3772
上一篇: iOS自定义警告框 OC 如何写可变参数的函数
下一篇: ios9适配,编译报错修改
淡暗云之遥
博客等级 码龄15年 61粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值