iOS主要知识总结--多线程之操作队列

操作队列(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 *)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 *)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 *)change context:(void *)context{
    NSLog(@"%@",change[NSKeyValueChangeOldKey]);
    NSLog(@"%@",change[NSKeyValueChangeNewKey]);
}
iOS主要知识总结--多线程之操作队列_第1张图片
xcode.png

你可能感兴趣的:(iOS主要知识总结--多线程之操作队列)