操作队列(NSOperation)
操作队列的几种常用方法
1. NSInvocationOperation
-(void)invocationOperationWithQueue
{
//01 创建一个非主队列
NSOperationQueue * queue = [[NSOperationQueue alloc]init];
//02 封装操作
NSInvocationOperation *op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download) object:nil];
NSInvocationOperation *op2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download) object:nil];
NSInvocationOperation *op3 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download) object:nil];
//03 添加操作到队列中(内部会自动调用start方法)
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:op3];
}
2. NSBlockOperation
-(void)blockOpertionQueue
{
//01 创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//02 封装操作
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"1---%@",[NSThread currentThread]);
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"2---%@",[NSThread currentThread]);
}];
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"3---%@",[NSThread currentThread]);
}];
//追加任务(系统自动开启子线程来执行追加的任务)
[op3 addExecutionBlock:^{
NSLog(@"4+++++%@",[NSThread currentThread]);
}];
//03 添加操作到队列中
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:op3];
以上的Block方式还有一种简便的实现方式:
//1)创建操作 2)把操作添加到队列
NSOperationQueue * queue = [[NSOperationQueue alloc]init];
[queue addOperationWithBlock:^{
NSLog(@"5+++++%@",[NSThread currentThread]);
}];
需要注意的是:这种实现方式虽然简单,但是无法的到操作对象。
拓展:
操作队列有一个属性可以用来设置最大并发数,默认情况下,这个数为-1,表示同一时间可以执行的任务的数量不受限制:
static const NSInteger NSOperationQueueDefaultMaxConcurrentOperationCount = -1;
当然,我们可以手动修改这个属性的值: queue.maxConcurrentOperationCount = 1;
如果修改成1的话,就表示同一时间只允许一个操作执行,也就是我们所说的串行,而在串行情况下,我们不可以给操作追加任务。
操作队列中的依赖和监听
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//01 创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
NSOperationQueue *queue2 = [[NSOperationQueue alloc]init];
//02 3操作
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"1---%@",[NSThread currentThread]);
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"2---%@",[NSThread currentThread]);
}];
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"3---%@",[NSThread currentThread]);
}];
NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"4---%@",[NSThread currentThread]);
}];
NSBlockOperation *op5 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"5++++++++%@",[NSThread currentThread]);
}];
//设置监听(在任务4执行完毕之后会立即来调用此方法)
op4.completionBlock = ^{
NSLog(@"任务执行完毕");
};
//设置依赖,通过设置依赖能控制操作的执行属性,本程序的操作执行顺序为:5-4-3-2-1
//注意:不能设置循环依赖
[op1 addDependency:op2];
[op2 addDependency:op3];
[op3 addDependency:op4];
[op4 addDependency:op5];
//03 添加操作到队列
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:op3];
[queue addOperation:op4];
//可以设置跨队列依赖
[queue2 addOperation:op5];
}
操作队列线程间的通信
具体细节请看注释,与前面的通信方式差别不大,代码如下:
@implementation ViewController
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//创建非主操作队列
NSOperationQueue *queue=[[NSOperationQueue alloc]init];
//封装操作
NSBlockOperation *op1=[NSBlockOperation blockOperationWithBlock:^{
//获得图片的URL
NSURL *url=[[NSURL alloc]initWithString:@"http://ww4.sinaimg.cn/bmiddle/695f1cd4jw1f5xetl00loj21y822t7wh.jpg"];
//将图片的二进制数据下载到本地
NSData *data=[NSData dataWithContentsOfURL:url];
//根据图片的二进制数据生成一张图片
UIImage *image=[[UIImage alloc]initWithData:data];
NSLog(@"%@",[NSThread currentThread]);
//操作队列线程间的通信方式
[[NSOperationQueue mainQueue]addOperationWithBlock:^{
self.imageV.image=image;
NSLog(@"%@",[NSThread currentThread]);
}];
}];
[queue addOperation:op1];
//添加监听
[op1 addObserver:self forKeyPath:@"isFinished" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];
}
//监听属性的改变
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
NSLog(@"%@",change[NSKeyValueChangeOldKey]);
NSLog(@"%@",change[NSKeyValueChangeNewKey]);
}
xcode.png
网友评论