NSOperation的基础
一.NSOperation
1.简介
NSOperation是一个抽象的基类,表示一个独立的计算单元,可以为子类提供有用且安全的线程创建,优先级,依赖,取消.
2.NSOperation和NSOperationQueue实现多线程的具体步骤:
(1)先将需要执行的操作封装到一个NSOperation对象中
(2)然后将NSOperation对象添加到NSOperationQueue中
(3)系统会⾃动将NSOperationQueue中的NSOperation取出来
(4)将取出的NSOperation封装的操作放到⼀条新线程中执⾏
3.NSOperation的子类
(1).NSInvocationOperation
(2).NSBlockOperation
(3).自定义子类继承NSOperation,实现内部相应的⽅法
二 NSInvocationOperation
1.简介
基于一个对象和selector来创建操作.如果已经有现有的方法来执行需要的任务,就可以使用这个类
2.创建并执行操作
{ NSInvocationOperation * op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downImage) object:nil];
// 如果我们想在一个NSOperation执行完毕后做一些事情,就调用NSOperation的setCompletionBlock方法来设置想做的事情
[op setCompletionBlock:^{
NSLog(@"完成");
}];
// 一个NSOperation对象可以通过调用start方法来执行任务,默认是同步执行的。
[op start];}
- (void)downImage {
[NSThread sleepForTimeInterval:1];
NSLog(@"%@",[NSThread currentThread]);
// NSLog(@"下载图片包");
}
三 .NSBlockOperation
1.简介
能够并发地执行一个或多个block对象,所有的block都执行完之后,操作才算结束
2.创建并执行操作
(1) {NSBlockOperation * op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%@",[NSThread currentThread]);
NSLog(@"第一个操作");
}];
[op start];//这里还是同步
(2)
NSBlockOperation * op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%@",[NSThread currentThread]);
NSLog(@"第一个操作");
}];
// 通过addExecutionBlock方法添加block操作,开启多个线程
[op addExecutionBlock:^{
NSLog(@"%@",[NSThread currentThread]);
NSLog(@"第二个操作");
}];
[op addExecutionBlock:^{
NSLog(@"%@",[NSThread currentThread]);
NSLog(@"第三个操作");
}];
[op start];//这里是异步
}
四 操作队列
1.简介
NSOperation是基于GCD的,把GCD的block封装成opertion,NSOperationQueue是全局队列封装
将NSOperation添加到一个NSOperationQueue(操作队列)中去执行,而且是异步执行的。
2.创建并执行操作
{NSOperationQueue * queue = [[NSOperationQueue alloc] init];
NSInvocationOperation * op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downImage) object:nil];
NSBlockOperation * op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"op2 - %@",[NSThread currentThread]);
}];
//添加NSOperation到NSOperationQueue中
//NSOperation添加到queue之后,通常短时间内就会得到运行。
// [queue addOperation:op];
// [queue addOperation:op2];
// waitUntilFinished yes 操作完成后执行下面的代码 no 先执行下面的代
//添加一个block形式的operation
[queue addOperationWithBlock:^{
NSLog(@"op3 - %@",[NSThread currentThread]);
}];
[queue addOperations:@[op,op2] waitUntilFinished:NO];
}
五 设置最大并发数
self.queue = [[NSOperationQueue alloc] init];
//最大并发数,这个功能NSOperation比较常用
self.queue.maxConcurrentOperationCount = 2;
for (NSInteger i = 0; i < 10; i++) {
NSInvocationOperation * op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downImage) object:nil];
NSLog(@"%@",@(i));
[self.queue addOperation:op];
}
六 设置依赖关系
{self.queue = [[NSOperationQueue alloc] init];
NSInvocationOperation * op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downImage) object:nil];
//设置优先级,数据量少看不出
op1.queuePriority = -4;
NSBlockOperation * op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"解压图片包");
}];
op2.queuePriority = 0;
NSBlockOperation * op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"观看漫画");
}];
op3.queuePriority = 4;
//添加NSOperation的依赖对象
// [op2 addDependency:op1];
// [op3 addDependency:op2];
//注意:不能创建环形依赖,如A依赖B,B依赖A,这是错误的
// [op1 addDependency:op3];
[self.queue addOperations:@[op1,op2,op3] waitUntilFinished:YES];}
七 暂停和继续
暂停一个queue不会导致正在执行的operation在任务中途暂停,只是简单地阻止调度新Operation执行。
暂停 :[queue setSuspended:YES];
继续:[queue setSuspended:NO];
八 取消
取消queue中所有的操作
[queue cancelAllOperations]