1. NSOperation实现多线程编程,需要和NSOperationQueue一起使用。
(1)先将要执行的操作封装到NSOperation中
(2)将NSOperation对象添加到NSOperationQueue中
(3)系统将自动将NSOPeration从NSOperationQueue中取出来,放到一个新的线程中去执行
2.NSOperation 的子类
NSOperation是一个抽象类,并没有封装操作的能力。因此要用到它的子类:
(1)NSInvocationOperation
(2)NSBlockOperation
3. NSInvocationOperation 和NSBlockOperation 的创建
(1)NSInvocationOperation的创建
NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(testAction) object:nil]; [operation start];
2017-06-18 10:17:04.165 demo[17389:3000329] 现在的线程----<NSThread: 0x60000007bf80>{number = 1, name = main}
注:操作对象默认在主线程中执行,只有加入到队列中才会开启新的线程。既默认情况下,如果操作没有放到Queue中只是同步执行,只有放到了NSOperationQueue中才会异步执行。
(2)NSBlockOperation的创建
(1)代码1
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"现在的线程----%@",[NSThread currentThread]); }]; [operation start];
打印结果:
2017-06-18 10:20:19.440 demo[17409:3003510] 现在的线程----<NSThread: 0x6080000713c0>{number = 1, name = main}
(2)代码2
- (void)viewDidLoad { [super viewDidLoad]; NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"现在的线程----%@",[NSThread currentThread]); }]; [operation addExecutionBlock:^{ NSLog(@"addExecution 的线程 ----%@",[NSThread currentThread]); }]; [operation start]; }
2017-06-18 10:26:31.545 demo[17436:3012476] 现在的线程----<NSThread: 0x608000079900>{number = 1, name = main}
2017-06-18 10:26:31.545 demo[17436:3012571] addExecution 的线程 ----<NSThread: 0x600000262f00>{number = 3, name = (null)}
注:NSBlockOperation 封装的操作数>1 那么就会开启新的线程。
4.NSOperationQueue
NSOperationQueue是操作对象的队列。将NSOperation对象放到NSOperationQueue里,系统会自动取出NSOperation,开启新线程 。
(1)NSOperationQueue添加操作的方式
//定义队列 NSOperationQueue *queue = [[NSOperationQueue alloc]init]; //将操作添加到队列 [queue addOperation:operation]; [queue addOperation:operation1]; [queue addOperation:operation2]; //用block的方式添加操作 [queue addOperationWithBlock:^{ NSLog(@"现在的线程----%@",[NSThread currentThread]); }];
(2)NSOperationQueue开启线程的方式
// // ViewController.m // demo // // Created by 登 on 2017/6/17. // Copyright © 2017年 登. All rights reserved. // #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(testAction) object:nil]; NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(testAction1) object:nil]; NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"现在的线程----%@",[NSThread currentThread]); }]; [operation2 addExecutionBlock:^{ NSLog(@"addExecution 的线程 ----%@",[NSThread currentThread]); }]; //定义队列 NSOperationQueue *queue = [[NSOperationQueue alloc]init]; //将操作添加到队列 [queue addOperation:operation]; [queue addOperation:operation1]; [queue addOperation:operation2]; //用block的方式添加操作 [queue addOperationWithBlock:^{ NSLog(@"现在的线程----%@",[NSThread currentThread]); }]; } -(void)testAction { NSLog(@"现在的线程----%@",[NSThread currentThread]); } -(void)testAction1 { NSLog(@"现在的线程----%@",[NSThread currentThread]); } @end
2017-06-18 10:49:44.163 demo[17479:3030821] 现在的线程----<NSThread: 0x60000007c380>{number = 5, name = (null)}
2017-06-18 10:49:44.163 demo[17479:3030826] 现在的线程----<NSThread: 0x60000007c040>{number = 3, name = (null)}
2017-06-18 10:49:44.163 demo[17479:3030820] 现在的线程----<NSThread: 0x60000007c2c0>{number = 4, name = (null)}
2017-06-18 10:49:44.163 demo[17479:3030842] 现在的线程----<NSThread: 0x60000007c540>{number = 6, name = (null)}
2017-06-18 10:49:44.164 demo[17479:3030846] addExecution 的线程 ----<NSThread: 0x60800006ec40>{number = 7, name = (null)}
注:
1.NSOPerationQueue将操作取出,每一个操作都会开启一个新的线程。所有的操作都是异步并发执行。
2.其中Operation2用NSBlockOPeration添加了两个任务,这两个任务开启两个线程,同样并发执行。