一、NSOperation的介绍
1、NSOperation的作用
配合使用NSOperation和NSOperationQueue实现多线程编程
2、实现多线程的具体步骤
1)将需要执行的操作封装到一个NSOperation对象中
2)将NSOperation对象添加到NSOperationQueue中
3)系统自动将NSOperationQueue中的NSOperation取出来,并且将封装的操作放到一条新线程中执行
3、NSOperation十个抽象类,并没有封装操作的能力,必须使用它的子类
4、子类的三种形式
1)NSInvocationOperation
2)NSBlockOpera
3)自定义继承自NSOperation的子类,实现内部相应的方法
二、结合代码
1、NSInvocationOperation的使用
1)没有添加到队列
- (void)useNSInvocationOperation { //1.封装操作 NSInvocationOperation * operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationTask) object:nil]; //开始执行 [operation1 start]; NSInvocationOperation * operation2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationTask2) object:nil]; [operation2 start]; } - (void)invocationTask { NSLog(@"invocationTask,%@",[NSThread currentThread]); } - (void)invocationTask2 { NSLog(@"invocationTask2,%@",[NSThread currentThread]); }
打印结果:
2016-03-14 17:53:59.638 NSoperation[3071:257804] invocationTask,<NSThread: 0x7f86fad06cb0>{number = 1, name = main} 2016-03-14 17:53:59.639 NSoperation[3071:257804] invocationTask2,<NSThread: 0x7f86fad06cb0>{number = 1, name = main}
注意事项:结果中可以看出如果没有放到队列中,默认同步执行,都在主线程。
2)添加到队列
1 - (void)useNSInvocationOperation 2 { 3 //1.封装操作 4 NSInvocationOperation * operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationTask) object:nil]; 5 6 NSInvocationOperation * operation2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationTask2) object:nil]; 7 8 //2.创建队列 9 NSOperationQueue * queue = [[NSOperationQueue alloc]init]; 10 queue.maxConcurrentOperationCount = 2;//最大线程数:2-3最好 11 12 //3.添加操作到队列 13 [queue addOperation:operation1]; 14 [queue addOperation:operation2]; 15 16 } 17 - (void)invocationTask 18 { 19 NSLog(@"invocationTask,%@",[NSThread currentThread]); 20 } 21 - (void)invocationTask2 22 { 23 NSLog(@"invocationTask2,%@",[NSThread currentThread]); 24 }
打印结果:
2016-03-14 17:57:33.192 NSoperation[3083:261277] invocationTask2,<NSThread: 0x7fd9b8f07ee0>{number = 2, name = (null)} 2016-03-14 17:57:33.192 NSoperation[3083:261278] invocationTask,<NSThread: 0x7fd9b8e13210>{number = 3, name = (null)}
根据打印结果可以看出加入队列之后,系统又开启了两条线程。
2、NSBlockOperation的使用
1 //1.封装操作 2 NSBlockOperation * operation1 = [NSBlockOperation blockOperationWithBlock:^{ 3 NSLog(@"NSBlockOperation---operation1,%@",[NSThread currentThread]); 4 }]; 5 //2.添加更多的操作 6 [operation1 addExecutionBlock:^{ 7 NSLog(@"NSBlockOperation---%@",[NSThread currentThread]); 8 }]; 9 10 [operation1 start];
输出结果:
2016-03-14 18:04:22.577 NSoperation[3105:266124] NSBlockOperation---operation1,<NSThread: 0x7f9e7850a1c0>{number = 1, name = main} 2016-03-14 18:04:22.577 NSoperation[3105:266206] NSBlockOperation---<NSThread: 0x7f9e785a4eb0>{number = 2, name = (null)}
注意事项:只要NSBlockOperation的封装操作数大于1,就会执行一部操作
3、给线程添加依赖
1 - (void)useNSInvocationOperation 2 { 3 //1.封装操作 4 NSInvocationOperation * operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationTask) object:nil]; 5 6 NSInvocationOperation * operation2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationTask2) object:nil]; 7 8 NSInvocationOperation * operation3 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationTask3) object:nil]; 9 10 //2.创建队列 11 NSOperationQueue * queue = [[NSOperationQueue alloc]init]; 12 queue.maxConcurrentOperationCount = 3;//最大线程数:2-3最好 13 14 //2.1设置依赖 15 [operation1 addDependency:operation3]; 16 [operation3 addDependency:operation2]; 17 18 //3.添加操作到队列 19 [queue addOperation:operation1]; 20 [queue addOperation:operation2]; 21 [queue addOperation:operation3]; 22 23 } 24 - (void)invocationTask 25 { 26 NSLog(@"invocationTask,%@",[NSThread currentThread]); 27 } 28 - (void)invocationTask2 29 { 30 NSLog(@"invocationTask2,%@",[NSThread currentThread]); 31 } 32 - (void)invocationTask3 33 { 34 NSLog(@"invocationTask3,%@",[NSThread currentThread]); 35 }
输出结果:
2016-03-14 18:12:21.066 NSoperation[3135:272293] invocationTask2,<NSThread: 0x7f845a54e500>{number = 2, name = (null)} 2016-03-14 18:12:21.067 NSoperation[3135:272293] invocationTask3,<NSThread: 0x7f845a54e500>{number = 2, name = (null)} 2016-03-14 18:12:21.067 NSoperation[3135:272293] invocationTask,<NSThread: 0x7f845a54e500>{number = 2, name = (null)}
根据结果可以看出先执行的2又执行的3最后执行的1,并没有根据添加到队列的顺序执行。
4、设置线程的优先级
1)operation1.queuePriority = NSOperationQueuePriorityHigh;
2)优先级的取值
NSOperationQueuePriorityVeryLow = -8L,
NSOperationQueuePriorityLow = -4L,
NSOperationQueuePriorityNormal = 0,
NSOperationQueuePriorityHigh = 4,
NSOperationQueuePriorityVeryHigh = 8