IOS程序猿阵线联盟-汇总各类技术干货

GCD使用小结

2017-09-05  本文已影响14人  天心鸥兹

GCD是iOS开发过程当中使用的比较频繁也比较重要的一块,往往项目里涉及到这方面的代码基本都是核心功能,维护的时候都小心翼翼,如果这里出问题给调试带来的难度是较大的。

下面我就来回顾温习一下GCD有关知识,如有纰漏和不足,欢迎指正。

本文主要通过一下几个模块来进行总结:

(1)多线程概念;

(2)几种多线程编程的优缺点;

(3) GCD中的几种队列类型;

(4)GCD中系统提供的常用dispatch方法;

多线程相关概念

1. 线程与进程:

进程:是指程序在计算机上的一次执行过程,例如开启微信,就是开启了一个进程,进程可包含多个线程。

线程:一组独立执行的代码段,一个线程同时只能执行一个任务,故而多线程并发就是指在同一时间执行多个任务。

iOS程序中,主线程(又称为UI线程)主要任务就是显示和刷新UI,也只有主线程可以直接修改UI,其他耗时操作会放在子线程(又称为异步线程)处理,这样可以提高程序的执行效率,提高资源的利用率。

主线程的堆栈大小是1M,其他线程开都是512KB,而且这个值不可更改,这也就意味着只要开启一个线程就会占用一部分内存,线程越多程序的性能也随之降低,所以一般不建议同时开启多个线程。

2. 线程按照执行方式又可细分:

同步线程:同步线程会阻塞当前线程然后开始执行该线程内的任务,任务执行完之后才会返回当前线程;

异步线程:异步线程不会阻塞当前线程,会开启其他线程去执行线程内的任务;

这里来说下串行和并发的概念:

串行队列:任务按先后顺序逐个执行,需要等待前一个任务执行完之后才开始执行下一个任务;

并发队列:多个任务按先后顺序一起开始执行,不用等待前一个任务执行完就可以执行下一个任务,因为任务添加的先后顺序间隔往往忽略不计,所以看起来像是一起执行的。

并发和并行也是两个不同的概念:并行是基于多核设备的,并行一定是并发,而并发不一定是并行。

3. 多线程编程中会经常遇到的问题:

死锁:两个或多个线程都在等待对方完成某个操作才能进行下一步操作,这时候就会发生死锁;

互斥锁:能够防止多线程抢夺资源造成的数据安全问题,但是需要消耗大量的资源;

原子属性(atomic)加锁:当属性以atomic修饰时,该属性就能支持互斥锁了,反之若以nonatomic修饰,表示忽略了线程安全;

上下文切换:当一个进程中有多个线程来回切换时,content switch用来记录执行状态,这是就会产生一些额外的开销。

几种多线程编程的优缺点

1. NSThread

优点:轻量级简单易用,可以直接操作线程对象;

缺点:需要自己管理线程的生命周期,线程同步;

2. NSOperation

优点:基于GCD对GCD的封装,比GCD更加面向对象,不需要关心线程管理;

缺点:使用时必须使用它的子类;

3. GCD

优点:基于C语言更底层更高效,并且不属于cocoa框架,简单易用,效率高,速度快,自动管理线程生命周期;

缺点:如果遇到较复杂的使用场景,很大可能会遇到死锁问题;

GCD中的几种队列类型

Dispatch block的执行最终都会放进某个队列中去执行,GCD中相关函数的创建一般都以dispatch开头:

(1)Mainqueue主线程串行队列:通过dispatch_get_main_queue来获取;

(2)Global queue 全局并发队列:通过dispatch_get_global_queue来获取,可以设置优先级;

(3)Custom queue 自定义队列:通过dispatch_queue_create来获取;

(4)Groupqueue 组队列:通过dispatch_group_create来获取;

GCD中系统提供的常用dispatch方法

1. Dispatch_after 延时添加到队列;

示例如下:

Dispatch_after

从打印信息来看Dispatch_after只是延时提交block,并没有延时后立即执行block,因此它不能实现精确控制。

2. Diapatch_apply :在给定的队列上多次执行某一任务,在主线程直接调用会阻塞主线程去执行block中的任务,所以一般把它放在异步队列中执行

示例如下:

Diapatch_apply

3. Dispatch_once:保证在app运行期间,block中的代码只执行一次

比如一个经典的使用场景:单例

Dispatch_once

4. Dispatch_barrier_async :栅栏作用

在并发队列中,等待在Dispatch_barrier之前加入的队列全部执行完,再执行Dispatch_barrier中的任务,执行完之后再开始执行Dispatch_barrier之后加入到队列的任务。

示例如下:

Dispatch_barrier_async
上一篇 下一篇

猜你喜欢

热点阅读