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];
打印结果
自定义类
-
CustomOperation
自定义类必须重载 main 函数
//
// CustomOperation.h
//
#import <Foundation/Foundation.h>
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];
打印结果
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] 任务一