多线程 - NSOperation&&NSOpe

2016-11-22  本文已影响9人  Hayder
内容结构框图

多线程-NSOperationQueue

NSOperation

NSOperation是个抽象类,并不具备封装操作的能力,必须使⽤它的子类.

使用NSOperation⼦类的方式有3种:

(1)NSInvocationOperation

(2)NSBlockOperation

(3)自定义子类继承NSOperation,实现内部相应的⽅法

说明:

1.一个NSoperation对象可以通过调用start方法来执行任务,默认是同步执行的。

//1.创建一个NSInvocationOperation对象
NSInvocationOperation *operation=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test) object:nil];

//执行操作
[operation start];

---------------------------------------------分隔线-------------------------------------------

//创建NSBlockOperation操作对象 
1.NSBlockOperation对象有一个block(任务) 只会同步执行
NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{

    NSLog(@"NSBlockOperation------%@",[NSThread currentThread]); //打印结果 num = 1   
    
}];
 
//开启执行操作
[operation start];

---------------------------------------------分隔线-------------------------------------------
2.NSBlockOperation对象有>1个block(任务) 就会异步执行

NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{

    NSLog(@"NSBlockOperation------%@",[NSThread currentThread]); //打印结果 num = 1
    
}];

/添加操作2
[operation addExecutionBlock:^{

     NSLog(@"NSBlockOperation1------%@",[NSThread currentThread]); //打印结果 num = 3
}];

/添加操作3
[operation addExecutionBlock:^{

     NSLog(@"NSBlockOperation1------%@",[NSThread currentThread]); //打印结果 num = 2
}];

//开启执行操作
[operation start];

2.将NSOperation添加到一个NSOperationQueue(操作队列)中去执行,而且是异步执行的。

NSOperation 与 NSOperationQueue实现多线程的具体步骤

NSOperationQueue *queue = [[NSOperationQueue alloc] init];  

1.将一个需要执行的任务封装到一个NSOperation对象中。

 NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{

    NSLog(@"NSBlockOperation------%@",[NSThread currentThread]); //打印结果 num = 1
    
}];

2.然后将NSOperation对象添加到NSOperationQueue中。
//3种方式
//1.添加一个operation
[queue addOperation:operation]; 

//2.添加一组operation
[queue addOperations:operations waitUntilFinished:NO];  

//3.添加一个block形式的operation
[queue addOperationWithBlock:^() {  

    NSLog(@"执行一个新的操作,线程:%@", [NSThread currentThread]);  
}];  

3.系统将Queue中的Operation取出,并在一条新的线程中执行

注意点:NSOperation添加到queue之后,绝对不要再修改NSOperation对象的状态。因为NSOperation对象可能会在任何时候运行,因此改变NSOperation对    象的依赖或数据会产生不利的影响。你只能查看NSOperation对象的状态, 比如是否正在运行、等待运行、已经完成等

添加NSOperation的依赖对象

1.当某个NSOperation对象依赖于其它NSOperation对象的完成时,就可以通过addDependency方法添加一个或者多个依赖的对象,只有所有依赖的对象都已经完成操作,当前NSOperation对象才会开始执行操作。另外,通过removeDependency方法来删除依赖对象。

//操作2 依赖于 操作1
[operation2 addDependency:operation1];  

依赖关系不局限于相同queue中的NSOperation对象,NSOperation对象会管理自己的依赖。因此完全可以在不同的queue之间的NSOperation对象之间创建依赖。

唯一的限制是不能创建环形依赖,比如A依赖B,B依赖A。这个就是错误的

依赖关系会影响到NSOperation在queue中的执行顺序。

NSOperation的执行顺序

1.NSOperation执行顺序由依赖决定
依赖是最先决定NSOperation执行顺序的,如果没有设置依赖,就看NSOpeartion的相对优先级。
2.NSOperation执行顺序由相对优先级决定
优先级只适用于相同Queue中的NSOperation。、
如果应用有多个opeation queue,每个queue的优先级等级是相互独立的。因此不同queue中的低优先级操作仍然可能比高优先中的要高。

设置队列的最大并发操作数量

NSOperationQueue可以设置并发数量,(不过并不是设置的并发数越多越好,设置过多就会影响性能。系统默认为5,一般不会进行修改)。如果设置为1,则最大并发数为1。Queue内部为串行执行。

设置方法
queue.maxConcurrentOperationCount = 1;  
或者
[queue setMaxConcurrentOperationCount:1];  

取消Operations

一旦添加到operation queue,queue就拥有了这个Operation对象并且不能被删除,唯一能做的事情是取消。可以调用OPeration的单次取消操作。也可以调用Queue的批量取消操作。

//单次取消
[operation cancel];  

//取消queue中的所有操作
[queue cancelAllOperations];

暂停和继续queue

暂停一个queue不会导致正在执行的operation在任务中途暂停,只是简单的阻止调度新的operation执行。
比如暂停一个queue来暂停queue还在等待中的任务。等待当前的operation执行完毕后再继续queue中operation的执行。

//暂停queue  
[queue setSuspended:YES];  

//继续queue  
[queue setSuspended:NO];
上一篇下一篇

猜你喜欢

热点阅读