iOS学习之GCD

简介:

  GCD(Grand Central Dispatch),是 Apple 开发的一个多核编程的解决方法。该方法在 Mac OS X 10.6 雪豹中首次推出,并随后被引入到了 iOS4.0 中。GCD 是一个替代诸如NSThread,NSOperationQueue, NSInvocationOperation 等技术的很高效和强大的技术。

  GCD 和 block 的配合使用,可以方便地进行多线程编程。

1.优势:

  1)  苹果官方为多核的并行运算提出的解决方案。

  2)  会自动利用更多的CPU内核。

  3)  会自动管理线程的生命周期(创建线程、调度任务、销毁线程)。

 

2.核心概念

  1)  任务:执行什么操作。block

  2)  队列:用来存放任务。

  串行队列:顺序,一个一个执行。一个任务执行完毕后才执行下一个任务。

  并发队列:同时,同时执行很多个任务。自动开启多个线程同时执行任务。并发功能只有在异步函数下才生效。

 

3.使用步骤:

  1)  定制任务

  确定想要做的事情。

  2)  将任务添加到队列中

  GCD会自动将队列中的任务取出,放到对应的线程中执行。

  任务的取出原则遵循队列的原则:先进先出,后进后出。

 

4.执行任务的函数

  1)同步方式  


dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
queue:队列
block:任务

2)异步方式


dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
queue:队列
block:任务

 同步和异步的区别:

  同步:在当前线程中执行。

  异步:在另一条线程中执行。

同步任务的作用

  1)  用户登录

  2)  下载任务1

  3)  下载任务2

 

5.术语

  1)  同步和异步决定了是否要开辟新线程。

  同步:在当前线程中执行任务,不具备开启新线程的能力。

  异步:在新的线程中执行任务,具备开启新线程的能力。

  2)  并发和串行决定了任务执行的方式。

  并发:多个任务同时执行。

  串行:一个任务执行完毕后,再执行下一个任务。

 

6.代码使用 


/*串行队列*/
/*创建队列
参数:1.队列标签。 2.队列属性。
*/
dispatch_queue_t queue = dispatch_queue_create(”dengw”,DISPATCH_QUEUE_SERIAL);
/*同步执行任务,不会开辟新线程,在当前线程中顺序执行。
一般只要使用“同步”执行,串行队列对添加的同步任务,立马执行*/
dispatch_sync(queue, ^{
    NSLog(@”%@”, [NSThread currentThread]);
});
/*异步执行任务,开辟新线程,在新线程中执行。开辟新线程的数量与队列模式有关。串行队列中异步执行只会开启一个新线程。*/
for(int I = 0; I < 10; I++){
dispatch_async(queue, ^{
        NSLog(@”%@”, [NSThread currentThread]);
});
}


/*并发队列:需要程序员释放。*/
/*创建队列
参数:1.队列标签。 2.队列属性。
*/
dispatch_queue_t queue = dispatch_queue_create(”dengw”,DISPATCH_QUEUE_CONCURRENT);
/*异步执行任务,开辟新线程,在新线程中执行。开辟新线程的数量程序员无法控制。*/
for(int I = 0; I < 10; I++){
dispatch_async(queue, ^{
        NSLog(@”%@”, [NSThread currentThread]);
});
}
/*同步执行任务,不开辟新线程,顺序执行*/
for(int I = 0; I < 10; I++){
dispatch_sync(queue, ^{
        NSLog(@”%@”, [NSThread currentThread]);
});
}


/*主队列,专门负责在主线程上调度任务。程序启动以后至少有一个主线程,则会创建主队列。*/
/*主队列不允许开辟新线程。不会在子线程调度任务。*/
/*获得主队列*/
dispatch_queue_t queue = dispatch_get_main_queue();
/*异步执行任务,在主队列中,只能顺序执行。*/
for(int I = 0; I < 10; I++){
/*异步:把任务放到主队列中,但不需要马上执行。*/
dispatch_async(queue, ^{
        NSLog(@”%@”, [NSThread currentThread]);
});
}
/*同步执行任务*/
for(int I = 0; I < 10; I++){
/*同步:把任务放到主队列中,需要马上执行。*/
/*阻塞*/
dispatch_sync(queue, ^{
        NSLog(@”%@”, [NSThread currentThread]);
});
}


/*全局队列:本质是并发队列。
与并发队列的区别:
1)全局队列没有名字,而并发队列有名字。
2)全局队列,是供所有的应用程序使用。
3)在MRC中,全局队列不需要释放,并发队列需要释放。*/
/*获得全局队列
参数:
参数1
iOS7中
DISPATCH_QUEUE_PRIORITY_HEGH    2 高优先级
DISPATCH_QUEUE_PRIORITY_DEFAULT  0 默认优先级
DISPATCH_QUEUE_PRIORITY_LOW   (-2) 低优先级
DISPATCH_QUEUE_PRIORITY_BACKGROUND    INT16_MIN 后台优先级(最低)
iOS8中
DISPATCH_QUEUE_PRIORITY_HEGH:QOS_CLASS_USER_INITIATED
DISPATCH_QUEUE_PRIORITY_DEFAULT:QOS_CLASS_USER_DEFAULT
DISPATCH_QUEUE_PRIORITY_LOW:QOS_CLASS_USER_UTILITY
DISPATCH_QUEUE_PRIORITY_BACKGROUND: QOS_CLASS_USER_BACKGROUND
参数2
保留参数。*/
dispatch_queue_t queue = dispatch_get_global_queue(QOS_CLASS_USER_DEFAULT,0);
/*异步执行任务*/
for(int I = 0; I < 10; I++){
dispatch_async(queue, ^{
        NSLog(@”%@”, [NSThread currentThread]);
});
}

7.各队列的执行效果:

 

全局并行队列

手动创建串行队列

主队列

同步(sync)

没有开启新线程。

串行执行任务。

没有开启新线程。

串行执行任务。

会死锁

异步(async)

有开启新线程。

并行执行任务。

有开启新线程。

串行执行任务。

没有开启新线程。

串行执行任务。

 

8.队列的选择

  1)串行队列异步执行

  开一条线程,顺序执行。

  效率不高,执行比较慢,资源占用小,省电。

  应用场景:一般3G网络,对性能要求不高。

  2)并发队列异步执行

  开启多条线程,并发执行。

  效率高,执行快,资源消耗大,费电。

  应用场景:WIFI网络,或需要快速响应,用户体验要求高,对任务执行顺序没有要求。

  3)  同步任务

  一般只会在并发队列,需要阻塞后续任务,必须等待同步任务执行完毕,再去执行其他任务。“依赖关系” 

 

9.线程间通信


/*从子线程回到主线程*/
dispatch_async(
    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    //执行耗时的异步操作…
    dispatch_async(dispatch_get_main_queue(), ^{
    //回到主线程,执行UI刷新操作
    });
});

10.延时操作

  1)方式一,调用NSObject的方法


//2秒后再调用run方法
[self performSelector:@selector(run) withObject:nil afterDelay:2.0];

2)方式二,使用GCD函数


dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    //2秒后再异步执行这里的代码
});

11.调度组(分组)

  应用场景:开发的时候,有的时候出现多个网络请求(每一个网络请求时间长短不一),都完成以后统一更新UI或通知用户。


/*实例化一个调度组*/
dispatch_group_t group = dispatch_group_create();
//队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//将任务添加到队列
dispatch_group_async(group, queue, ^{
    NSLog(@”A %@”, [NSThread currentThread]);
});
dispatch_group_async(group, queue, ^{
    NSLog(@”B %@”, [NSThread currentThread]);
});
//获得所有调度组里面的异步任务完成的通知
/*在调度组完成通知里,可以跨队列通信*/
dispatch_group_notifity(group, queue, ^{
    //异步的
    NSLog(@”finished”);
});

12.一次性执行,常见于单例模型中代码使用。


static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    //只执行一次
    NSLog(@”hi”);
});



目录
相关文章
|
4月前
|
API Swift C语言
探索iOS开发:Swift中的异步编程与GCD应用
【8月更文挑战第4天】在iOS开发的海洋中,掌握Swift语言的航向是至关重要的。本文将引领你深入理解Swift中的异步编程概念,并借助Grand Central Dispatch(GCD)这一强大的工具,来简化并发编程的复杂性。我们将通过实际代码示例,展现如何在iOS应用中高效地管理后台任务和提升用户界面的响应性。
85 3
|
5月前
|
前端开发 开发工具 Swift
学习iOS开发的准备
准备学习iOS开发?确保有Mac和最新Xcode,先学好编程基础特别是Swift。利用Apple官方文档、在线课程和书籍作为资源。熟悉Xcode及Git,通过实践项目和开源代码积累经验。深研架构模式、核心框架和优化技巧。加入开发者社区,关注行业动态,持续学习。
50 1
|
7月前
|
iOS开发 开发者 UED
iOS 中的并发编程:GCD 与 Operation 的对比与实践
【4月更文挑战第23天】 在iOS开发中,为了提高应用的性能和响应能力,理解并合理运用并发编程是至关重要的。本文将深入探讨两种主要的并发模式:Grand Central Dispatch (GCD) 和 NSOperation。我们将比较它们的优势和局限性,并通过代码示例演示如何在实际场景中应用这两种技术来优化应用性能。文章旨在为开发者提供一个清晰的指南,以便在选择适合自己项目的并发工具时做出明智的决策。
|
7月前
|
调度 iOS开发 开发者
iOS 中的并发编程模式:理解 GCD 和 Operation Queues
【4月更文挑战第19天】 在现代 iOS 应用开发中,有效地管理线程和并发是至关重要的。为了确保用户界面的流畅性和后台任务的高效运行,开发者需要掌握并发编程技术。本文深入探讨了两种主要的并发模式:Grand Central Dispatch (GCD) 和 Operation Queues。我们将分析它们的工作原理,比较它们的特点,并通过实际代码示例说明如何在 iOS 应用中实现高效的并发处理。通过本文,读者将获得在 iOS 平台上进行多线程开发的实用知识,以及如何根据不同的应用场景选择最合适的并发工具。
|
7月前
|
API 调度 iOS开发
多线程和异步编程:什么是 GCD(Grand Central Dispatch)?如何在 iOS 中使用 GCD?
多线程和异步编程:什么是 GCD(Grand Central Dispatch)?如何在 iOS 中使用 GCD?
81 1
|
安全 前端开发 Android开发
鸿蒙开发|鸿蒙系统的介绍(为什么要学习鸿蒙开发|鸿蒙系统的官方定义|鸿蒙和安卓、ios的对比)
鸿蒙开发学习是一项探索性的工作,旨在开发一个全场景分布式操作系统,覆盖所有设备,让消费者能够更方便、更直观地使用各种设备。
685 6
鸿蒙开发|鸿蒙系统的介绍(为什么要学习鸿蒙开发|鸿蒙系统的官方定义|鸿蒙和安卓、ios的对比)
|
安全 调度 C语言
iOS多线程之GCD-同步、异步、并发、串行、线程组、栅栏函数、信号量等全网最全的总结
iOS多线程之GCD-同步、异步、并发、串行、线程组、栅栏函数、信号量等全网最全的总结
1006 1
|
iOS开发
iOS UIKit Dynamics Demo 学习地址列表
iOS UIKit Dynamics Demo 学习地址列表
52 0
|
XML JSON 编解码
IM通讯协议专题学习(九):手把手教你如何在iOS上从零使用Protobuf
接上篇《金蝶随手记团队的Protobuf应用实践(原理篇)》,本文将以iOS端的Objective-C代码为例,图文并茂地向您菔救绾卧趇OS工程中快速使用Protobuf,希望对你有帮助。
176 0
IM通讯协议专题学习(九):手把手教你如何在iOS上从零使用Protobuf
|
iOS开发
iOS开发 - 写一个刷新的控件(未封装,适合新手学习,查看原理)
iOS开发 - 写一个刷新的控件(未封装,适合新手学习,查看原理)
150 0
iOS开发 - 写一个刷新的控件(未封装,适合新手学习,查看原理)