NSOperation是iOS中一种多线程技术的实现,基于GCD,比GCD更加面向对象,和类NSOperationQueue配合使用。NSOperation是一个抽象类,我们不能直接使用它,应该使用它的子类NSInvocationOperation或者NSBlockOperation。
NSInvocationOperation
当我们有需要在子线程中执行的方法时,使用NSInvocationOperation比较方便。
NSInvocationOperation *oper1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];
/* 1.放到队列中的操作都是在子线程中执行
* 2.如果不做特殊操作依赖,队列中的操作都是并发的
*/
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 主线程队列
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
// 设置队列最大并发数
queue.maxConcurrentOperationCount = 4;
// 把Operation添加到队列中,系统会自动取出队列中的Operation放到子线程中执行
[queue addOperation:oper1];
- (void)run {
NSLog(@"正在下载图片1----%@",[NSThread currentThread]);
}
// 2015-12-26 23:00:48.854 NSOperation学习[8816:1300341] 正在下载图片1----<NSThread: 0x7fbc50c18270>{number = 2, name = (null)}
NSBlockOperation
把要在子线程中执行的代码放到Block中。
NSBlockOperation *oper2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"正在下载图片2----%@",[NSThread currentThread]);
}];
NSBlockOperation *oper3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"正在下载图片3----%@",[NSThread currentThread]);
}];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 4;
[queue addOperation:oper2];
[queue addOperation:oper3];
/*
2015-12-26 23:17:09.399 NSOperation学习[8838:1309995] 正在下载图片2----<NSThread: 0x7fdeaaf11d30>{number = 2, name = (null)}
2015-12-26 23:17:09.399 NSOperation学习[8838:1309994] 正在下载图片3----<NSThread: 0x7fdeaaf2d440>{number = 3, name = (null)}
*/
Operation中的依赖关系
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation *oper1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"正在下载图片1----%@",[NSThread currentThread]);
}];
[oper1 setCompletionBlock:^{
/*
* 当oper1执行完毕时执行这个block中的代码,这个block所在的线程不是
* 主线程,可能与oper1所在线程一样,也可能不一样。
*
*/
NSLog(@"完成下载图片1----%@",[NSThread currentThread]);
}];
NSBlockOperation *oper2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"正在下载图片2----%@",[NSThread currentThread]);
}];
NSBlockOperation *oper3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"正在下载图片3----%@",[NSThread currentThread]);
}];
// oper3依赖oper1,只有1执行完成之后才能执行3
[oper3 addDependency:oper1];
// oper3依赖oper2
[oper3 addDependency:oper2];
[queue addOperation:oper1];
[queue addOperation:oper2];
[queue addOperation:oper3];
/*
2015-12-27 01:04:10.575 NSOperation学习[9003:1333576] 正在下载图片1----<NSThread: 0x7ff9e1c33970>{number = 2, name = (null)}
2015-12-27 01:04:10.575 NSOperation学习[9003:1333577] 正在下载图片2----<NSThread: 0x7ff9e1f1eba0>{number = 3, name = (null)}
2015-12-27 01:04:10.576 NSOperation学习[9003:1333579] 完成下载图片1----<NSThread: 0x7ff9e1d3a7b0>{number = 4, name = (null)}
2015-12-27 01:04:10.576 NSOperation学习[9003:1333577] 正在下载图片3----<NSThread: 0x7ff9e1f1eba0>{number = 3, name = (null)}
*/