IOS —— NSOperation的作用以及其与GCD的区别 - 随笔

哈喽,每日分享时间。今天要说说的是NSOperation这个类,以及和GCD的关系和区别

事不宜迟


1.NSOperation是什么? 

我们知道,GCD是基于底层C语言封装的API。那么NSOperation是什么呢?

"灯灯灯灯" 揭晓答案

NSOperation实际上是基于GCD的Objective-C语言封装的对象。也就是所谓的父子关系。

既然是父子关系,俩者肯定有区别

那么区别是什么呢?

1.GCD是无法取消加入到队列中的任务的,而NSOperation则可以取消未运行任务。注意是未运行。

2.GCD队列任务运行顺序是先进先出(FIOI)也就是先进队列的任务先执行,而NSOperation可以随意调配任务执行顺序

备注:GCD任务虽然也可以进行调配,但是需要复杂繁琐的代码及功能块进行控制(barrier、group等)

3.NSOperation任务支持KVO(监听),可以方便监听任务状态(开始,执行中,结束等),而GCD则不支持。

4.NSOperation可以设置同一队列中的任务优先级,也可以设置并发任务的执行顺序。GCD只能设置不同队列的执行优先级

5.NSOperation支持自定义,可以封装繁琐复杂任务代码,提高复用性。GCD则不能。

 

2.NSOperation怎么用?

1.NSOperation本身是不能直接使用的抽象类。可以通过使用系统自带的子类NSInvocationOperation/NSBlockOperation,或则是使用自行封装的Operation子类

2.Operation对象都是调用start方法执行任务的。也有例外,比如说"NSOperationQueue"

例:

NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector('对象方法') object:nil];

[op start];

那么子类NSInvocationOperation/NSBlockOperation 俩者又有何区别?

1.当单独使用NSInvocationOperation时,NSInvocationOperation是在主线程进行操作,并且没有开启新线程。使用的是同步执行的方式。

2.当使用NSBlockOperation时,NSBlockOperation是在主线程进行同步执行操作。新增子线程进行并发执行操作。

对的没错是本体,NSBlockOperation本身具备添加子线程方法"addExeutionBlock"。以下是例子。

 ['实例对象' addExecutionBlock:^{
       //方法
    }];

大致讲完子类,我们来说说另外一种启动方式:NSOperationQueue

如果不用start启动NSOperation子类进行操作任务的话,也可以通过将子类对象直接添加到操作对象队列直接执行任务,并且默认开启新线程,执行的是并发操作。

直接添加的方式有俩种以下代码示例~~

//通过方法添加
//<1> :- (void)addOperation:(NSOperation *)op;
["实例的队列对象" addOperation:"Op对象"];

//通过block直接添加
// <2>: - (void)addOperationWithBlock:(void (^)(void))block;
["实例的队列对象"  addOperationWithBlock:^{
     
}];

3.NSOperation还有什么用?

1.添加依赖

NSOperation可以通过添加依赖来操作对象的先后执行顺序。

添加方法:addDependency:

删除方法:removeDependency:

例: 假设任务一依赖于任务二

['任务1' addDeperdency:'任务2'];

添加依赖后,此时的任务1需要在任务2执行完毕后才会执行

注意事项:

1.如果任务出现互相依赖的情况,那么程序将会陷入死循环loop。

2.当被依赖的任务2未执行的情况下,执行任务1时。程序将会运行失败,并且报错。

3.依赖关系必须在任务添加到队列前才会有效。

4.添加依赖的操作对象必须等待所有操作完成时(操作在未运行的情况下被取消也算作完成),才会执行操作。

2.取消

NSOperation可以通过指令来取消对象未执行的操作。注意,是未 执 行。已执行、操作中的对象是不能被取消的。

//单项取消未 执 行 操作
['任务1' cancel]; 
//取消所有未执行的操作
['线程' cancelAllOperation];

3.优先级

 NSOperation可以通过优先级指令来设定同一队列的操作顺序先后。

//这是优先级函数
typedef NS_ENUM(NSInteger, NSOperationQueuePriority) {
    NSOperationQueuePriorityVeryLow = -8L,
    NSOperationQueuePriorityLow = -4L,
    NSOperationQueuePriorityNormal = 0,
    NSOperationQueuePriorityHigh = 4,
    NSOperationQueuePriorityVeryHigh = 8
};

//这是使用方法
['任务1' setOperationPriorty:NSOperationQueuePriorityNormal];

注意事项:操作优先级并不是绝对优先的,还需要看当前操作的依赖关系以及操作加入队列的顺序。当加入的操作依赖关系未处理,或者晚于同优先级操作进入队列时,当前操作将会延后处理。

4.暂停、继续

NSOperation可以通过指令简单的阻止新操作的执行,并且不会打断正在执行的操作。

//这是代码 queue代表当前线程
//暂停
[self.queue setSuspendecl:YES]; 
//结束暂停
[self.queue setSuspendecl:NO];

5.监听状态

 NSOperation的操作对象中,开发者提供了以下五种监听状态给开发者

1.isExcuting ,该状态代表任务执行中。

2.isFinished ,该状态代表任务结束。当isFinished = YES时,其他依赖操作队列才会开始执行。操作队列也是根据这状态判断决定是否将操作任务移出队列

3.isCancel   ,该状态代表任务已经取消执行。

4.isAsynchronours ,该状态表示任务是同步执行还是异步执行。

5.isReady ,该状态表示任务准备中,一般作用于有依赖任务的任务。一般isReady = NO。当依赖任务isFinished = Yes时,isReady 才会将当前状态改为YES;


学习总结:

即使说NSOperation功能众多而且便利,但是多数多线程操作一般都交于GCD处理,因为GCD更靠近底层代码,速度快这是关键。只有部分特殊要求(取消任务、设置任务执行顺序、监听任务状态、封装任务操作等)才会用到。

 over~

猜你喜欢

转载自www.cnblogs.com/UUUUgua/p/9895401.html
今日推荐