iOS 之NSOperation(一)

一、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

原文地址:https://www.cnblogs.com/fengzhihao/p/5276675.html