NSThread、GCD和NSOperation的详解与区别

1.基本概念

进程:操作系统上每一个可以执行的程序。

线程:进程中的任务,必须在线程中执行。

每一个进程,至少包含一个线程,就是我们常说的主线程。

2.任务在线程中的执行

任务在线程中一次一个的依次执行。一个线程同时只能执行一个任务。

如果我们需要同时执行多个任务,就需要多个线程,每次执行一个任务。

为了提高用户体验,我们就需要使用多线程,比如:网络请求,下载图片。

3.线程操作的三种方式

(1)NSThread

轻量级的线程操作,需要我们自己创建线程,调度任务,销毁线程

① 后台线程:performSelectorInBackground

② 主线程;performSelectorOnMainThread

③ 以上两个线程,只要继承自NSObject的对象,都可以调用

④ 手动开辟一个分线程:NSThread *  thread = [NSThread alloc] initWithTarget:<#(id)#> selector:<#(SEL)#> object:<#(id)#>

[thread start];

⑤ 自动开辟分线程:[NSThread detachNewThreadSelector:<#(SEL)#> toTarget:<#(id)#> withObject:<#(id)#>]

⑥ 判断线程是否为主线程:[NSThread isMainThread]

⑦ 线程休眠:[NSThread sleepForTimeInterval:2]

⑧ 查看当前线程:[NSThread currentThread]

(2)GCD

Grand Central Dispatch的缩写  宏大的的中央调度  基于C语言

<1>GCD存在于libdispatch.dylib这个库中,这个调度库包含了GCD的所有的东西,但任何IOS程序,默认就加载了这个库,在程序运行的过程中会动态的加载这个库,不需要我们手动导入。

<2>GCD中的函数大多数都以dispatch开头。

GCD的优势:

1.他是苹果公司为多核的并行运算提出的解决方案;

2.它在工作的时候会自动利用更多的处理器核心;

3.不用关心线程代码的实现, 即不需要关心什么时候开起线程, 关闭线程.  GCD会负责创建线程调度你的任务;

4.只需要创建出来你要执行的任务, 然后把任务添加到适当的队列中.

dispatch queue  (调度队列)

核心理念: 将长期运行的任务拆分成多个工作单元, 并把这些工作单元添加调度队列

(意思就是将任务添加到队列当中)

串行和并行队列

串行队列,添加到队列中的任务按照添加顺序依次执行。FIFO,先进先出。

并行队列,多个任务同时执行,需要多条分线程。

同步与异步

同步:前一个任务不执行完,后边的任务等待前一个任务执行完,再执行

异步:不管前一个任务是否执行完毕,后一个任务都直接执行

总结:

1.同步异步决定了是否会开启分线程.

2.串行并行决定了任务在线程中是一次只执行一个任务还是并发执行多个任务.

3.并行队列只有在异步函数下才有效

GCD 使用队列(queue)管理线程,队列分为三种

1.自定义的串行和并行队列。

2.运行在分线程的四个优先级不同全局并行队列,globalQueue。

3.运行在主线程的串行队列,mianQueue。(在主线程中,主队列中使用同步任务会造成死锁)

在一组并行任务执行完毕后做某个操作,使用dispatch_group

多个线程对同一个变量的修改需要加锁。保证一个变量同时只能被一个线程修改,当这个线程修改完毕后,其他线程才能修改。可以使用:NSLock,@synchronized。

单例模式:是一个类在系统中只有一个实例对象,通过全局的一个入口点对这个实例对象进行访问.

iOS中单例模式的实现方法有两种:非ARC和ARC + GCD;

(3)NSOperation 

纯OC代码 操作队列,对GCD的封装.它是一个抽象类,只能使用其子类对象。系统提供了两个子类对象,分别是 NSInvocationOperation 和 NSBlockOperation。通常我们自定义 NSOperation 的子类,重写子类的 main 方法,把需要在分线程执行的任务放在 main 方法里。然后把 NSOperation 对象添加到 NSOperationQueue 中,就会自动在分线程执行 main 方法。

4.GCD 和 NSOperation 进行比较。

(1).NSOperation 是对 GCD 的封装,面相对象的类,GCD 只是一组方法 API。

(2).NSOperation 可以实现一些 GCD 中实现不了,或者实现比较复杂的功能。比如:设置最大并发数,设置线程间的依赖关系。

(3).实现某个多线程功能,使用 GCD,简单易用。实现某个多线程模块,使用 NSOperation,方便类的管理。

5.nonatomic,atomic

nonatomic,非原子性,多线程访问修改不加锁。

atomic,原子性,多线程访问加锁。

iOS 推荐我们使用 nonatomic,移动端的开发没有复杂的多线程场景,不加锁解锁可以提高效率。

系统的可变对象,NSMutableArray,NSMutabelString 都是线程不安全的,多线程修改,需要加锁。

原文地址:https://www.cnblogs.com/CJH5209/p/6046497.html