您的位置:首页 > 运维架构

GCD与NSOperation

2016-05-29 16:05 197 查看
线程的自旋锁和互斥锁:前者是不断询问,后者是坐等通知

GCD是苹果公司为多核运算提供的一套纯C语言解决方案

我们只需告诉GCD执行什么任务即可

GCD的任务需要指定两个方面(核心):

任务:执行什么操作

队列:用来存放任务

使用:

创建任务来确定要做的事情,将任务添加到队列中

GCD会遵从FIFO原则(先进先出)来去除队列中的任务放到对应的线程中执行

GCD用来执行任务的函数:同步和异步

同步:在当前线程中执行任务

异步:开辟一条子线程来执行任务

GCD执行任务的队列:并发队列和串行队列

并发队列(concurrent):让多个任务同时执行,只有在异步的函数下才可以执行

串行队列(serial):让任务一个接着一个的执行

所以:同步执行、并行队列中与同步执行、串行队列的结果一样,不开线程,顺序执行

主队列(全局串行队列,main):

在主线程中执行,且等待主线程中正在执行的代码执行完毕后执行

所以,主队列,同步执行会产生死锁现象

因为同步执行要求任务一个一个执行,但是主队列又要求队列中的任务等待主线程任务结束后执行

于是主队列的任务等待主线程中的任务结束后执行

主线程中的任务执行到主队列时又等待主队列的任务执行完毕

对于主队列同步执行的死锁问题:可放入异步执行中执行,或将同步执行换成异步执行

主队列和串行队列区别:

串行队列:任务一个接一个的执行,上一个任务完成下一个才执行

主队列:任务虽是一个接一个的执行,但要等待主线程没有代码执行的时候才执行

全局队列(global):

本质就是并行队列,但没有名称

MRC中并发队列由create创建,所以需要release,但全局队列不需要

在ARC中不需要考虑内存释放

一般我们都使用全局队列

队列与队列间可嵌套调用,如验证密码时,可通过异步嵌套同步执行

GCD还可用于延迟操作(dispatch_after(时间,队列,任务)),一次性执行(只执行一次,dispatch_once)与调度组(group)

调度组:创建组,给组里添加任务并指明队列,通过notify获取组的完成通知,执行任务完成后操作

NSOperation

OC中基于GCD的面向对象的封装,苹果推荐使用

它对GCD进行了优化,使用比GCD更简单,提供了一些GCD不好实现的功能

不用关心线程及线程的生命周期

NSOperation是一个抽象类(只能继承,不能实现,通常用来约束子类)

我们通常使用的都是其子类:NSInvocationOperation、NSBlockOperation、自定义operation

关于使用:

先将需要执行的操作封装到一个NSOperation对象中

然后将NSOperation对象添加到NSOperationQueue中即可

系统会自动将NSOperationQueue中的NSOperation取出来

随后将取出的NSOperation封装的操作放到一条新线程中执行

NSInvocationOperation:

默认情况下,对象通过start方法执行,但是执行时并不会开启一条新的线程去执行

只有将对象放到一个队列中,才会异步执行

NSBlockOperation:

只要对象封装的操作数(add添加)>1,就异步执行

NSOperationQueue:将NSOperation添加到队列后,默认执行就会从同步变成异步

当前队列:[NSOperationQueue currentQueue]

主队列:[NSOperationQueue mainQueue]

添加到主队列的操作,最终都会在主线程上执行

GCD           VS(比较)  
    NSOperation  

GCD:

iOS4.0推出,主要针对多核CPU做了优化的纯C语言解决方案

通过将任务添加到队列,再将队列添加到同步/异步的执行任务的函数

提供了一些NSOperation不具备的功能:一次执行、延迟操作、调度组

NSOperation:

iOS2.0推出,但iOS4.0后又被重写

重写是用OC语言基于GCD的面相对象的封装

是将封装好的任务添加到队列中来执行,此时任务默认为异步并发执行,不用在手动指定

提供的方便操作:最大并发数,队列的暂停 / 继续,取消所有的操作,指定操作间的依赖关系(GCD中可以异步嵌套同步实现)

对于NSOperation而言

操作执行过程:

1.把操作添加到队列执行

2.去线程池取空闲的线程,如果没有就创建线程

3.把操作交给线程执行

4.执行完成后,将线程再放回线程池中

重复2、3、4直到所有操作完成

通过设置NSOperation对象在queue中的优先级,来改变操作的执行优先级

iOS8以后推荐使用服务质量

操作完成可以被监听:-(void)setCompletionBlock:(void(^)(void))block;

可以通过操作依赖来保证执行顺序:[B addDependency: A]; 操作B依赖操作A,但要注意相互依赖
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: