block与GCD--43:NSOperation 与NSOpe

2018-08-02  本文已影响0人  皆为序幕_

NSOperation

关于NSInvocationOperation

- (IBAction)invocationOperation:(id)sender {
    //初始化Operation子类
    NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(run) object:nil];
    //调用start方法开始执行操作,一旦执行操作就会调用run方法
    [operation start];
}
-(void)run{
    NSLog(@"0--%@",[NSThread currentThread]);
}
invocationOperation.png

关于NSBlockOperation

- (IBAction)blockOperation:(id)sender {
    //初始化Operation子类
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        //在主线程
        NSLog(@"1--%@",[NSThread currentThread]);
    }];
    [operation start];
}
blockOperationlog.png

注: 如果添加的操作多的话,blockOperationWithBlock: 中的操作也可能会在其他线程(非当前线程)中执行,这是由系统决定的,并不是说添加到 blockOperationWithBlock: 中的操作一定会在当前线程中执行

- (IBAction)blockOperation:(id)sender {
    //初始化Operation子类
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        //在主线程
        NSLog(@"1--%@",[NSThread currentThread]);
    }];
  
    //添加额外的任务(在子线程执行)
    [operation addExecutionBlock:^{
        NSLog(@"2--%@",[NSThread currentThread]);
    }];
    [operation addExecutionBlock:^{
        NSLog(@"3--%@",[NSThread currentThread]);
    }];
    [operation addExecutionBlock:^{
        NSLog(@"4--%@",[NSThread currentThread]);
    }];
    [operation addExecutionBlock:^{
        NSLog(@"5--%@",[NSThread currentThread]);
    }];
    [operation addExecutionBlock:^{
        NSLog(@"6--%@",[NSThread currentThread]);
    }];
    [operation addExecutionBlock:^{
        NSLog(@"7--%@",[NSThread currentThread]);
    }];
    [operation addExecutionBlock:^{
        NSLog(@"8--%@",[NSThread currentThread]);
    }];
    [operation addExecutionBlock:^{
        NSLog(@"9--%@",[NSThread currentThread]);
    }];
    [operation start];
}
blockOperationlog.png

自定义子类继承NSOperation

#import <Foundation/Foundation.h>
@interface SSOperation : NSOperation
@end

#import "SSOperation.h"
@implementation SSOperation
#pragma mark-需要执行的任务
-(void)main{
    if (!self.isCancelled) {
        NSLog(@"0--%@",[NSThread currentThread]);
    }
}
@end


- (IBAction)SSOperationOperation:(id)sender {
    SSOperation *operation = [[SSOperation alloc]init];
    [operation start];
}
SSOperationlog.png

关于NSOperationQueue

NSOperationQueue 一共有两种队列:主队列、自定义队列。其中自定义队列同时包含了串行、并发功能。下边是主队列、自定义队列的基本创建方法和特点

主队列

- (IBAction)creatOperationQueue1:(id)sender {    
    //主队列
    NSOperationQueue *queue = [NSOperationQueue mainQueue];
    //创建操作(任务)
    //创建--NSInvocationOperation
    NSInvocationOperation *op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(run1) object:nil];
    NSInvocationOperation *op2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(run2) object:nil];
    //创建--NSBlockOperation
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"-1--%@",[NSThread currentThread]);
    }];
    NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"-2--%@",[NSThread currentThread]);
    }];
    //自定义(需要继承NSOperation,执行的操作需要放在这个自定义类的main中)
    SSOperation *op5 = [[SSOperation alloc]init];
    //添加任务队列中
    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue addOperation:op3];
    [queue addOperation:op4];
    [queue addOperation:op5];
    //也可以直接创建任务到队列中去
    [queue addOperationWithBlock:^{
        NSLog(@"-3--%@",[NSThread currentThread]);
    }];
}
-(void)run1{
    NSLog(@"-run1--%@",[NSThread currentThread]);
}
-(void)run2{
    NSLog(@"-run2--%@",[NSThread currentThread]);
}
主队列log.png

自定义队列(系统会自动异步执行NSOperation中的操作)

- (IBAction)creatOperationQueue1:(id)sender {
    //创建队列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    //创建操作(任务)
    //创建--NSInvocationOperation
    NSInvocationOperation *op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(run1) object:nil];
    NSInvocationOperation *op2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(run2) object:nil];
    //创建--NSBlockOperation
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"-1--%@",[NSThread currentThread]);
    }];
    NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"-2--%@",[NSThread currentThread]);
    }];
    //自定义队列(需要继承NSOperation,执行的操作需要放在这个自定义类的main中)
    SSOperation *op5 = [[SSOperation alloc]init];
    //添加任务队列中
    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue addOperation:op3];
    [queue addOperation:op4];
    [queue addOperation:op5];
    //也可以直接创建任务到队列中去
    [queue addOperationWithBlock:^{
        NSLog(@"-3--%@",[NSThread currentThread]);
    }];
}
-(void)run1{
    NSLog(@"-run1--%@",[NSThread currentThread]);
}
-(void)run2{
    NSLog(@"-run2--%@",[NSThread currentThread]);
}
自定义队列log.png

NSOperationQueue设置最大并发操作数

//maxConcurrentOperationCount = 1
- (IBAction)creatOperationQueue2:(id)sender {
    //创建队列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];    
    //设置为1就成了串行队列
    queue.maxConcurrentOperationCount = 1;
    [queue addOperationWithBlock:^{
        NSLog(@"-1--%@",[NSThread currentThread]);
    }];
    [queue addOperationWithBlock:^{
        NSLog(@"-2--%@",[NSThread currentThread]);
    }];
    [queue addOperationWithBlock:^{
        NSLog(@"-3--%@",[NSThread currentThread]);
    }];
    [queue addOperationWithBlock:^{
        NSLog(@"-4--%@",[NSThread currentThread]);
    }];
}
maxConcurrentOperationCount = 1
//maxConcurrentOperationCount = 2
- (IBAction)creatOperationQueue2:(id)sender {
    //创建队列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    //设置最大并发操作数(不管加入队列有多少操作,实际队列并发数为2)
    queue.maxConcurrentOperationCount = 2;
    
    [queue addOperationWithBlock:^{
        [NSThread sleepForTimeInterval:2]; // 模拟耗时操作
        NSLog(@"-1--%@",[NSThread currentThread]);
    }];
    [queue addOperationWithBlock:^{
        [NSThread sleepForTimeInterval:2]; // 模拟耗时操作
        NSLog(@"-2--%@",[NSThread currentThread]);
    }];
    [queue addOperationWithBlock:^{
        [NSThread sleepForTimeInterval:2]; // 模拟耗时操作
        NSLog(@"-3--%@",[NSThread currentThread]);
    }];
    [queue addOperationWithBlock:^{
        [NSThread sleepForTimeInterval:2]; // 模拟耗时操作
        NSLog(@"-4--%@",[NSThread currentThread]);
    }];
}
maxConcurrentOperationCount = 2

NSOperationQueue设置队列挂起与取消

- (IBAction)createOperationQueueSuspended:(id)sender {
    //创建队列
    self.queue = [[NSOperationQueue alloc]init];
    self.queue.maxConcurrentOperationCount = 1;
    [self.queue addOperationWithBlock:^{
        NSLog(@"-1--%@",[NSThread currentThread]);
        [NSThread sleepForTimeInterval:1.0];
    }];
    [self.queue addOperationWithBlock:^{
        NSLog(@"-2--%@",[NSThread currentThread]);
        [NSThread sleepForTimeInterval:1.0];
    }];
    [self.queue addOperationWithBlock:^{
        NSLog(@"-3--%@",[NSThread currentThread]);
        [NSThread sleepForTimeInterval:1.0];
    }];
    [self.queue addOperationWithBlock:^{
        NSLog(@"-4--%@",[NSThread currentThread]);
        [NSThread sleepForTimeInterval:1.0];
    }];
    //设置队列挂起或者取消的话都必须是在block方法执行完之后才有效
    [self.queue addOperationWithBlock:^{
        for(NSInteger i = 0;i<5;i++){
            NSLog(@"-5--%zd---%@",(long)i,[NSThread currentThread]);
        }
    }];
}
#pragma mark-设置队列挂起
- (IBAction)operationSetSuspended:(id)sender {
    if(self.queue.suspended){
        //恢复队列,继续执行
        self.queue.suspended  = NO;
    }else{
        //挂起(暂停队列)
        self.queue.suspended  = YES;
    }
}
#pragma mark-设置队列取消(取消就意味着后续队列不再执行,再次启动需要重新加入队列)
- (IBAction)operationSetCancel:(id)sender {
    [self.queue cancelAllOperations];
}

NSOperationQueue设置队列依赖

- (IBAction)createOperationQueueSetDependency:(id)sender {

    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
 
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"down1---%@",[NSThread currentThread]);
    }];
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"down2---%@",[NSThread currentThread]);
    }];
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"down3---%@",[NSThread currentThread]);
    }];
    
    //设置依赖(op1和op3执行完之后才执行2)
    [op2 addDependency:op1];
    [op2 addDependency:op3];

    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue addOperation:op3];    

    //监听一个操作的执行完成
    [op2 setCompletionBlock:^{
        NSLog(@"执行完成");
    }];
}

注:一定要避免相互依赖,比如

[op3 addDependency:op1];
[op1 addDependency:op3];    //错误的写法---相互依赖
设置队列依赖.png

监控NSOperation对象的属性

NSOperation在队列里的优先级

//iOS8以前的优先级(queuePriority)
typedef NS_ENUM(NSInteger, NSOperationQueuePriority) {
    NSOperationQueuePriorityVeryLow = -8L,
    NSOperationQueuePriorityLow = -4L,
    NSOperationQueuePriorityNormal = 0,
    NSOperationQueuePriorityHigh = 4,
    NSOperationQueuePriorityVeryHigh = 8
};

//iOS8以后的优先级(qualityOfService)
typedef NS_ENUM(NSInteger, NSQualityOfService) {
     NSQualityOfServiceUserInteractive = 0x21,//最高优先级,用于用户交互事件
    NSQualityOfServiceUserInitiated = 0x19,//次高优先级,用于用户需要马上执行的事件
    NSQualityOfServiceUtility = 0x11,//默认优先级,主线程和没有设置优先级的线程都默认为这个优先级
    NSQualityOfServiceBackground = 0x09,//普通优先级,用于普通任务
    NSQualityOfServiceDefault = -1//最低优先级,用于不重要的任务
}
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"down1---%@",[NSThread currentThread]);
    }];
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"down2---%@",[NSThread currentThread]);
        
    }];
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"down3---%@",[NSThread currentThread]);
        
    }];
    NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"down4---%@",[NSThread currentThread]);
    }];
 
    op3.qualityOfService = NSQualityOfServiceUserInteractive;

    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue addOperation:op3];
    [queue addOperation:op4];

优先级.png
上一篇 下一篇

猜你喜欢

热点阅读