iOS——GCD多线程
1> 概述
Grand Central Dispatch (GCD)是Apple开发的一种多核编程技术。主要用于优化应用程序以支持多核处理器以及其他对称多处理系统。
GCD提供函数实现多线程开发,性能更高,功能也更加强大。
它首次发布在Mac OS X 10.6 ,iOS 4及以上也可用。
2> 核心概念
任务:具有一定功能的代码段。一般是一个block或者函数
分发队列:GCD以队列的方式进行工作,FIFO
GCD会根据分发队列的类型,创建合适数量的线程执行队列中的任务
3> GCD中的队列
串行队列(SerialQueue):一次只执行一个任务。Serial queue通常用于同步访问特定的资源或数据。当你创建多个Serial queue时,虽然它们各自是同步执行的,但Serial queue与Serial queue之间是并发执行的。SerialQueue能实现线程同步
并行队列(Concurrent):可以并发地执行多个任务,虽然遵守FIFO(先进先出),但由于各个任务被分配到不同的线程执行,因此其完成时 间有可能不同,即:后分配的任务有可能先执行完成;并发队列一定需要和异步执行的任务(使用dispatch_async())结合起来使用才有意义。
- 主队列:主队列也是一个串行队列,主队列中的任务都在主线程中执行。
4> 串行队列(SerialQueue)
- 第一种:系统提供的创建串行队列的方法,实际上主队列的创建方法

1 // 第一种获取方式:里面的任务是在主线程依次去执行,dispatch_get_main_queue()获取主队列
2 dispatch_queue_t queue = dispatch_get_main_queue();
3 // 往队列里面添加任务
4 dispatch_async(queue, ^{
5 NSLog(@"这是第一个任务,当前线程是:%@, 是否主线程 :%d ", [NSThread currentThread], [[NSThread currentThread] isMainThread]);
6 });

- 第二种:自己创建的队列


1 // 参数1:队列的名字(苹果推荐使用反向域名去命名)
2 // 参数2:队列的类型(串行队列、并行队列),这种方式创建的队列,它会自己去开辟一个子线程去完成队列里面的任务
3 dispatch_queue_t queue = dispatch_queue_create("com.zf.mySerialQueue", DISPATCH_QUEUE_SERIAL);
4
5 dispatch_async(queue, ^{
6 NSLog(@"这是第一个任务,当前线程是:%@, 是否主线程 :%d ", [NSThread currentThread], [[NSThread currentThread] isMainThread]);
7 });


5> 并行队列
- 第一种:系统提供的创建并行队列的方法


1 // 参数1:优先级PRIORITY(有四个,没有明显的区别)
2 // 参数2:系统保留字,苹果预留的参数为了以后去使用,目前没有用到,填写0
3 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
4
5 dispatch_async(oneQueue, ^{
6 NSLog(@"这是第一个任务。。。线程是:%@, 是否主线程:%d", [NSThread currentThread], [[NSThread currentThread] isMainThread]);
7 });


- 第二种:自己创建的队列
使用的方法同串行队列,只有创建函数参数2给定队列的类型的时候,将DISPATCH_QUEUE_SERIAL替换为DISPATCH_QUEUE_CONCURRENT


1 // 参数1:队列的名字(苹果推荐使用反向域名去命名)
2 // 参数2:队列的类型(串行队列、并行队列),这种方式创建的队列,它会自己去开辟一个子线程去完成队列里面的任务
3 dispatch_queue_t queue = dispatch_queue_create("com.zf.mySerialQueue", DISPATCH_QUEUE_CONCURRENT);
4
5 dispatch_async(queue, ^{
6 NSLog(@"这是第一个任务,当前线程是:%@, 是否主线程 :%d ", [NSThread currentThread], [[NSThread currentThread] isMainThread]);
7 });


6> GCD功能函数
- dispatch_async(dispatch_queue_t queue, ^(void)block) // 异步任务,往队列中添加任务,任务会排队执行
参数1(dispatch_queue_t queue):添加任务的队列
参数2(^(void)block):Block,主要是在添加过程中进行一些操作,操作代码就写在Block中
- dispatch_after() //往队列中添加任务,任务不但会排队,还会在延迟的时间点执行


1 /*
2 函数
3 dispatch_after(dispatch_time_t when, dispatch_queue_t queue, ^(void)block);
4
5 // 系统封装的代码快(一般使用)
6 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(具体的浮点型数字 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
7 延迟执行的内容
8 });
9
10 */
11 // 参数1:延迟的时间,使用dispatch_time()初始化
12 // 参数2:队列
13 // 参数3:Block
14 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
15 NSLog(@"3.0秒后");
16 });


dispatch_time(dispatch_time_t when, int64_t delta)对延迟时间进行初始化
参数1:为起始时间,系统宏定义,一般使用 DISPATCH_TIME_NOW
参数2:为延迟的具体时间类型为 int64_t,变量的类型为:具体浮点型数字 * 时间单位(系统的宏定义,可以根据实际情况选用)
- dispatch_apply() //往队列中添加任务,任务会重复执行n次


1 /*
2 dispatch_apply(size_t iterations, dispatch_queue_t queue, ^(size_t) {
3 code
4 });
5 */
6 dispatch_queue_t queue = dispatch_queue_create("com.zf.myQueue", DISPATCH_QUEUE_CONCURRENT);
7 // 参数1:添加任务的个数
8 // 参数2:队列
9 // 参数3:Block,这个Block没有变量名,需要自己添加
10 dispatch_apply(10, queue, ^(size_t index) {
11 NSLog(@"%zu", index);
12 });


注:函数dispatch_apply()的参数3Block没有变量名,需要自己添加
dispatch_group_async() //将任务添加到队列中,并添加分组标记
dispatch_group_notify() //将任务添加到队列中,当某个分组的所有任务执行完之后,此任务才会执行
1 // dispatch_group_t主要用于把一些不相关的任务归为一组
2 // 组里面放的是队列
3 // dispatch_group_async作用是往组里面的队列添加任务
4 // dispatch_group_notify作用:监听组里面的任务,等到组里面的任务全部执行完成之后,才会执行它里面的任务
5
6 //1、创建队列
7 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
8 //2、创建组
9 dispatch_group_t group = dispatch_group_create();
10 // 3、往组里面的队列添加任务(注意:在执行notify之前最起码要向队列中放置一个任务才可以,否则,notify里面的任务不会等待小组里面的其他任务执行完才执行。)
11 dispatch_group_async(group, queue, ^{
12 NSLog(@"这是第一个任务。。。线程是:%@, 是否主线程:%d", [NSThread currentThread], [[NSThread currentThread] isMainThread]);
13 });
14
15 dispatch_group_notify(group, queue, ^{
16 NSLog(@"我是最后一个任务,组里面的其他任务都执行完毕之后,我就会执行");
17 });- dispatch_barrier_async() //将任务添加到队列中,此任务执行的时候,其他任务停止执行


1 // 数据库的读取。。。可以并发执行,通过 GCD 里面的并行队列去实现
2 // 数据库的写入。。。。只能串行执行,通过 GCD 里面的串行队列去实现
3 // 但是真正的项目,肯定是既有数据的读取,也有数据库的写入。。。如何解决该问题:dispatch_barrier_async 在它之前的任务可以并发去执行,在他之后的任务也可以去并发执行
4 dispatch_queue_t queue = dispatch_queue_create("concurrentTest",DISPATCH_QUEUE_CONCURRENT);
5 dispatch_async(queue, ^{
6 NSLog(@"这是第一个读取数据的任务。。。线程是:%@, 是否主线程:%d", [NSThread currentThread], [[NSThread currentThread] isMainThread]);
7 });
8
9 dispatch_barrier_async(queue, ^{
10 NSLog(@"正在在数据库里写东西,不要打扰我");
11 });
12
13 dispatch_async(queue, ^{
14 NSLog(@"这是第二个读取数据的任务。。。线程是:%@, 是否主线程:%d", [NSThread currentThread], [[NSThread currentThread] isMainThread]);
15 });


- dispatch_once() //任务添加到队列中,但任务在程序运行过程中,只执行一次
dispatch_once: 该函数接收一个dispatch_once用于检查该代码块是否已经被调度的谓词(是一个长整型,实际上作为BOOL使用)。它还接收一个希望在应用的生命周期内仅被调度一次的代码块。
dispatch_once 不仅意味着代码仅会被运行一次,而且还是线程安全的,这就意味着你不需要使用诸如@synchronized之类的来防止使用多个线程或者队列时不同步的问题。
运用代码(单例的完整定义)


1 static MyHandle *handle = nil;
2
3 + (MyHandle *)sharedMyHandle
4 {
5 // 在GCD中只执行一次,用于记录内容是否执行过
6 static dispatch_once_t onceToken;
7
8 dispatch_once(&onceToken, ^{
9 handle = [MyHandle new];
10 });
11
12 return handle;
13 }


- dispatch_sync() //同步任务 将任务添加到队列中,block不执行完,下面代码不会执行
与 dispatch_async() 的区别:
dispatch_async() 不等 block 体执行完,就去执行下面的代码,会在另外的线程中执行
dispatch_sync() 会等待 block 体执行完成之后,才会去执行 block 体外面的代码,会在当前的线程中执行,当前线程有可能是主线程,也有可能是子线程
- dispatch_async_f() //将任务添加到队列中,任务是函数非block


1 // 函数
2 void function(void * str){
3 NSLog(@"这是一个函数,%s",str);
4 }
5
6 // 第一个参数:队列
7 // 第二个参数:函数参数的内容
8 // 第三个参数:函数
9 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
10 dispatch_async_f(queue, @"passValue", function);
iOS——GCD多线程的更多相关文章
- iOS GCD多线程介绍
GCD:是纯C语言写的,是苹果公司为多核的并行运算提出的解决方案. GCD的两个核心概念: - 任务 - 队列 将任务添加到队列中 GCD会自动将队列中的任务取出,放到对应的线程中执行 任务的取出遵循 ...
- iOS 开发多线程篇—GCD的常见用法
iOS开发多线程篇—GCD的常见用法 一.延迟执行 1.介绍 iOS常见的延时执行有2种方式 (1)调用NSObject的方法 [self performSelector:@selector(run) ...
- iOS开发多线程篇—GCD介绍
iOS开发多线程篇—GCD介绍 一.简单介绍 1.什么是GCD? 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 2.GCD的优势 G ...
- iOS开发多线程篇—GCD的基本使用
iOS开发多线程篇—GCD的基本使用 一.主队列介绍 主队列:是和主线程相关联的队列,主队列是GCD自带的一种特殊的串行队列,放在主队列中得任务,都会放到主线程中执行. 提示:如果把任务放到主队列中进 ...
- iOS开发多线程篇—GCD的常见用法
iOS开发多线程篇—GCD的常见用法 一.延迟执行 1.介绍 iOS常见的延时执行有2种方式 (1)调用NSObject的方法 [self performSelector:@selector(run) ...
- ios开发:GCD多线程
ios有三种多线程编程技术,分别是NSThread,Cocoa NSOperation和GCD,GCD全称Grand Central Dispatch 是Apple开发的一个多核编程的解决方法,在iO ...
- iOS开发——GCD多线程详解
GCD多线程详解 1. 什么是GCD Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,简单来说,GCD就是iOS一套解决多线程的机制,使用GCD能够最大限度简化多线程 ...
- iOS之多线程开发NSThread、NSOperation、GCD
原文出处: 容芳志的博客 欢迎分享原创到伯乐头条 简介iOS有三种多线程编程的技术,分别是:(一)NSThread(二)Cocoa NSOperation(三)GCD(全称:Grand Centr ...
- iOS开发多线程篇—GCD简介
iOS开发多线程篇—GCD介绍 一.简单介绍 1.什么是GCD? 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 2.GCD的优势 G ...
随机推荐
- 【HDOJ】3071 Gcd & Lcm game
刚开始看这个题目,觉得没法做.关键点是数据小于100.因此,可以枚举所有小于100的素因子进行位压缩.gcd就是求最小值,lcm就是求最大值.c++有时候超时,g++800ms.线段树可解. /* 3 ...
- windows权限错误
1.installer "内部错误 2203 C:\WINDOWS\Installer\354787.ipi,-2147287035” 用户的local\Temp目录没有system权限 2 ...
- POJ 3159 Candies 解题报告(差分约束 Dijkstra+优先队列 SPFA+栈)
原题地址:http://poj.org/problem?id=3159 题意大概是班长发糖果,班里面有不良风气,A希望B的糖果不比自己多C个.班长要满足小朋友的需求,而且要让自己的糖果比snoopy的 ...
- PowerDesigner一些小技巧
1.安装PD v12.0版 2.由pdm生成建表脚本时,字段超过15字符就发生错误(oracle) 原因未知,解决办法是打开PDM后,会出现Database的菜单栏,进入Database - Edit ...
- iphone4s丢失如何找回
iphone4s丢失如何找回 iphone4s手机丢了怎么办,其实苹果手机自带找回功能,但是前提你得打开了icloud这款软件. 方法/步骤 1 在手机的设置里找到icloud设置,如图. 2 点击进 ...
- Mac osx 下配置ANT
一般安装过程如下: 1:sudo sh (会提示你输入当前用户的密码) 2:cp apache-ant.1.8.2-bin.zip /usr/local 3:cd /usr/local 4:unzip ...
- 【CSS】Intermediate7:Pseudo Elements
1.selector:pseudo element{property:value;} 2.first-letter first-line CSS3:: 与pseudo class 区别 old br ...
- RTCP
RTCP RTCP协议将控制包周期发送给所有连接者,应用与数据包相同的分发机制.低层协议提供数据与控制包的复用,如使用单独的UDP端口号.RTCP执行下列四大功能: (1) 主要是提供数据发布的质量反 ...
- 一分钟快速入门openstack
一.它是什么,能干什么想认识一个事物,必须先弄明白它是什么,能干什么.首先说一下,openstack是一个搭建云平台的一个解决方案,说他不是个软件,但是我觉得说是一个软件,能够让大家认识更清晰些.op ...
- 打开链接(C# / 默认浏览器)
System.Diagnostics.Process.Start("http://www.baidu.com/");