NSOperation

NSOperation是面向对象的多线程框架,是对GCD第封装。NSOperation是一个抽象类,我们使用时必须先实现它,不过系统已经给我们提供了两个子类NSInvocationOperation和NSBlockOperation。NSOperation相当于GCD里面的任务,NSOperationQueue相当于GCD里的队列。

系统自带子类

  • NSInvocationOperation
//NSInvocationOperation通过taget-action执行任务,下面这个任务会在主线程执行
NSInvocationOperation *invocationOp = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(function) object:nil];
//记得要调用start
[invocationOp start];
-(void)action {
    for (int i = 0; i < 2; i++) {
        NSLog(@"我是invocationOp_%d___%@",i,[NSThread currentThread]);
    }
}
  • NSBlockOperation
//NSBlockOperation通过block来执行任务,下面这个任务会在主线程执行
    NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"我是NSBlockOperation");
    }];
//必须加载start之前,否则会报错,使用addExecutionBlock加入的任务,会并发执行
    [blockOp addExecutionBlock:^{
        NSLog(@"我是NSBlockOperation====第一个任务");
    }];
    [blockOp addExecutionBlock:^{
        NSLog(@"我是NSBlockOperation====第二个任务");
    }];
    [blockOp addExecutionBlock:^{
        NSLog(@"我是NSBlockOperation====第3个任务");
    }];
    [blockOp addExecutionBlock:^{
        NSLog(@"我是NSBlockOperation====第4个任务");
    }];
    [blockOp addExecutionBlock:^{
        NSLog(@"我是NSBlockOperation====第5个任务");
    }];
    //记得要调用start
    [blockOp start];

打印结果


屏幕快照 2016-11-11 下午4.24.15.png

自定义类

  • CustomOperation
    自定义类必须重载 main 函数
//
//  CustomOperation.h
//
#import 
typedef void (^OperationBlock)(void);
@interface CustomOperation : NSOperation
@property (nonatomic, copy) OperationBlock operationBlock;
+(CustomOperation *)RunBlock:(OperationBlock)block;
@end
//
//  CustomOperation.m
//
#import "CustomOperation.h"
@implementation CustomOperation
+(CustomOperation *)RunBlock:(OperationBlock)block{
    CustomOperation *customOp = [[CustomOperation alloc] init];
    customOp.operationBlock = block;
    return customOp;
}
-(void)main{
//    NSLog(@"我是自定义的Opertion");
    if (self.operationBlock) {
        self.operationBlock();
    }
}
@end
//下面任务会运行在主线程
CustomOperation *op = [CustomOperation RunBlock:^{
        NSLog(@"我是自定义的Opertion");
    }];
    [op start];
    //打印
    //    2016-11-11 15:28:52.311 多线程[2486:140730] 我是自定义的Opertion

NSOperationQueue

我们可以通过设置NSOperationQueue的maxConcurrentOperationCount参数来实现NSOperation的并行和串行。

  • 默认为-1,不限制并行和串行
    customQueue.maxConcurrentOperationCount = -1;
  • 为1时,串行执行,串行执行时,可能会创建新的线程,但是无论任务在哪个线程中都会按顺序执行
    customQueue.maxConcurrentOperationCount = 1;
  • 并行执行,最大线程数不超过n个,当然系统会限制最高的线程数,当这个数大于系统的值时,会按系统的值执行
    customQueue.maxConcurrentOperationCount = 3;
1、通过- (void)addOperation:(NSOperation *)op;函数添加任务
//自定义队列
    NSOperationQueue *customQueue = [[NSOperationQueue alloc] init];  
    NSInvocationOperation *invocationOp = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(action) object:nil];
    NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 2; i++) {
            NSLog(@"我是blockOp______%d___%@",i,[NSThread currentThread]);
        }
    }];
    CustomOperation *customOp = [CustomOperation RunBlock:^{
        for (int i = 0; i < 2; i++) {
            NSLog(@"我是customOp_____%d___%@",i,[NSThread currentThread]);
        }
    }];
    //通过addOperation将任务加入队列
    [customQueue addOperation:invocationOp];
    [customQueue addOperation:blockOp];
    [customQueue addOperation:customOp];

打印结果


屏幕快照 2016-11-11 下午4.41.13.png
2、通过addOperationWithBlock:(void (^)(void))block函数添加任务
//通过- (void)addOperationWithBlock:(void (^)(void))block直接添加任务,会创建新线程,并发执行,
    [customQueue addOperationWithBlock:^{
        for (int i = 0; i < 2; i++) {
            NSLog(@"_____%d___%@",i,[NSThread currentThread]);
        }
    }];

获取主队列方法
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];

设置依赖

NSOperation可以设置依赖,及一个任务可以依赖另外一个任务执行,比如执行完A任务后我们再执行B任务

NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    CustomOperation *task1 = [CustomOperation RunBlock:^{
        NSLog(@"任务一");
        sleep(2);
    }];
    CustomOperation *task2 = [CustomOperation RunBlock:^{
        NSLog(@"任务二");
    }];
    //设置依赖,任务2依赖任务一
    [task2 addDependency:task1];
    [queue addOperation:task1];
    [queue addOperation:task2];
    
    //设置依赖结果
//    2016-11-11 16:11:11.125 多线程[2893:166914] 任务一
//    2016-11-11 16:11:13.200 多线程[2893:166916] 任务二
    
    //不设置依赖结果
//    2016-11-11 16:10:05.655 多线程[2873:165884] 任务二
//    2016-11-11 16:10:05.656 多线程[2873:165897] 任务一

你可能感兴趣的:(NSOperation)