一、基本概念
1、进程
进程是指在系统中正在运行的一个应用程序
每个进程之间是相互独立的, 每个进程均运行在其专用且受保护的内存空间内(可以在 Mac 的活动指示器查看当前系统内运行的进程)
2、线程
一个进程要想执行任务,必须要有线程,至少有一条线程
一个进程的所有任务都是在线程中执行
3、进程和线程的比较
- 线程是 CPU 调用的最小单位
- 进程是 CPU 分配资源和调度的单位
- 一个程序可以对应多个进程,一个进程中可有多个线程,但至少要有一条线程
- 同一个进程内的线程共享进程资源
4、多线程
一个进程可以开启多条线程,每条线程可以并行执行不同的任务. 这个技术可以提高程序的执行效率
4.1、多线程原理
同一时间,CPU 只能处理一条线程, 只有一条线程在工作;
多线程并发执行,其实是 CPU 快速的在多条线程之间调度(切换);
如果 CPU 调度线程的时间足够快, 就造成了多线程并发执行的假象。
4.2、多线程的优点和缺点
优点
- 能适当的提高程序的执行效率
- 能适当提高资源利用率(CPU 内存利用率)
缺点
- 创建多线程是有开销的,iOS 下主要成本包括: 内核数据结构,(大约1KB), 栈空间(子线程512KB, 主线程1MB, 也可以使用 -setStackSize: 设置, 但必须是4K 的倍数, 而且最小是16K), 创建线程大约需要90毫秒的创建时间
- 如果开启大量线程, 会降低程序的性能
- 线程越多,CPU 在调度线程上的开销就越大
- 程序设计更加复杂: 比如线程之间的通信, 多线程的数据共享
二、iOS开发中实现多线程的方式
pthread: 跨平台,适用于多种操作系统,可移植性强,是一套纯C语言的通用API,且线程的生命周期需要程序员自己管理,使用难度较大,所以在实际开发中通常不使用。
NSThread: 基于OC语言的API,是轻量级的,使得其简单易用,面向对象操作。线程的生命周期由程序员管理,在实际开发中偶尔使用。通过@selector指定要执行的方法,代码分散。
GCD: 基于C语言的API,充分利用设备的多核,旨在替换NSThread等线程技术。线程的生命周期由系统自动管理,在实际开发中经常使用。通过Block指定要执行的方法,代码集中利用阅读和维护。
NSOperation: 基于OC语言API,底层是GCD,增加了一些更加简单易用的功能,使用更加面向对象。线程生命周期由系统自动管理,在实际开发中经常使用。
三、GCD与NSOperation 的区别
1.GCD的核心是C语言写的系统服务,执行和操作简单高效,因此NSOperation底层也通过GCD实现,换个说法就是NSOperation是对GCD更高层次的抽象,这是他们之间最本质的区别.因此如果希望自定义任务,建议使用NSOperation;
2.依赖关系,NSOperation可以设置两个NSOperation之间的依赖,第二个任务依赖于第一个任务完成执行,GCD无法设置依赖关系,不过可以通过dispatch_barrier_async来实现这种效果;
3.KVO(键值对观察),NSOperation和容易判断Operation当前的状态(是否执行,是否取消),对此GCD无法通过KVO进行判断;
4.优先级,NSOperation可以设置自身的优先级,但是优先级高的不一定先执行,GCD只能设置队列的优先级,无法在执行的block设置优先级;
5.继承,NSOperation是一个抽象类实际开发中常用的两个类是NSInvocationOperation和NSBlockOperation,同样我们可以自定义NSOperation,GCD执行任务可以自由组装,没有继承那么高的代码复用度;
6.效率,直接使用GCD效率确实会更高效,NSOperation会多一点开销,但是通过NSOperation可以获得依赖,优先级,继承,键值对观察这些优势,相对于多的那么一点开销确实很划算,鱼和熊掌不可得兼,取舍在于开发者自己;