iOS开发多线程篇之NSOperation

一、NSOperation简介


1、简单说明

  • NSOperation的作⽤:配合使用NSOperation和NSOperationQueue也能实现多线程编程
  • NSOperation和NSOperationQueue实现多线程的具体步骤:

(1)先将需要执行的操作封装到一个NSOperation对象中
(2)然后将NSOperation对象添加到NSOperationQueue中
(3)系统会⾃动将NSOperationQueue中的NSOperation取出来
(4)将取出的NSOperation封装的操作放到⼀条新线程中执⾏

2、NSOperation的子类

  • NSOperation是个抽象类,并不具备封装操作的能力,必须使⽤它的子类
  • 使用NSOperation⼦类的方式有3种:

(1)NSInvocationOperation
(2)NSBlockOperation
(3)自定义子类继承NSOperation,实现内部相应的⽅法

3、执行

执行一个operation有两种方:

  • 第一种是自己手动的调用start这个方法,这种方法调用会在当前调用的线程进行同步执行,所以在主线程里面自己一定要小心的调用,不然就会把主线程给卡死,还不如直接用GCD呢。
  • 第二种是将operation添加到operationQueue中去,这个也是我们用得最多的也是提倡的方法。NSOperationQueue会在我们添加进去operation的时候尽快进行执行。当然如果NSOperationQueue的maxConcurrentOperationCount如果设置为1的话,进相当于FIFO了。

二、 操作


1、NSInvocationOperation子类

注意:操作对象默认在主线程中执行,只有添加到队列中才会开启新的线程。即默认情况下,如果操作没有放到队列中queue中,都是同步执行。只有将NSOperation放到一个NSOperationQueue中,才会异步执行操作

1.1 创建并执行操作

 NSInvocationOperation *operation=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];
[operation start];//开始执行任务(同步执行)

1.2 事件响应

- (void)run {
    NSLog(@"%@",[NSThread currentThread]);
}

1.3 执行结果

**2016-07-06 10:15:32.593 ****类库****[6716:2832599] <NSThread: 0x166456b0>{number = 1, name = main}**

2、NSBlockOperation子类

2.1 创建并执行操作

NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^(){  
    NSLog(@"执行了一个新的操作,线程:%@", [NSThread currentThread]);  
}];  
 // 开始执行任务(这里还是同步执行)  
[operation start]; 

2.2.通过addExecutionBlock方法添加block操作

NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^(){  
NSLog(@"执行第1次操作,线程:%@", [NSThread currentThread]);  
}];  

[operation addExecutionBlock:^() {  
NSLog(@"又执行了1个新的操作,线程:%@", [NSThread currentThread]);  
}];  

[operation addExecutionBlock:^() {  
NSLog(@"又执行了1个新的操作,线程:%@", [NSThread currentThread]);  
}];  

[operation addExecutionBlock:^() {  
NSLog(@"又执行了1个新的操作,线程:%@", [NSThread currentThread]);  
}];  

// 开始执行任务  
[operation start];  

结果

**2016-07-06 10:28:12.476 ****类库****[6730:2835101] 2****又执行了****1****个新的操作,线程:****<NSThread: 0x17d3ca10>{number = 2, name = (null)}**
**2016-07-06 10:28:12.476 ****类库****[6730:2835035] 1****执行第****1****次操作,线程:****<NSThread: 0x17d19150>{number = 1, name = main}**
**2016-07-06 10:28:12.477 ****类库****[6730:2835101] 3****又执行了****1****个新的操作,线程:****<NSThread: 0x17d3ca10>{number = 2, name = (null)}**
**2016-07-06 10:28:12.477 ****类库****[6730:2835035] 4****又执行了****1****个新的操作,线程:****<NSThread: 0x17d19150>{number = 1, name = main}**

可以看出,这4个block是并发执行的,也就是在不同线程中执行的

3、NSOperationQueue

NSOperationQueue的作⽤:

(1) NSOperation可以调⽤start⽅法来执⾏任务,但默认是同步执行的
(2) 如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会自动异步执行NSOperation中的操作
(3) 添加操作到NSOperationQueue中,自动执行操作,自动开启线程

3.1 创建队列

NSOperationQueue * queue = [[NSOperationQueue alloc] init];

3.2 将操作添加到队列当中

//第一种方式 
[queue addOperation:operation1];

//第二种方式
[queue addOperationWithBlock:^{    
    NSLog(@"NSBlockOperation%@",[NSThread currentThread]);
}];

3.3 示例

NSOperationQueue * queue = [[NSOperationQueue alloc] init];


NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];

NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^(){
    NSLog(@"2:NSBlockOperation:%@", [NSThread currentThread]);
}];

[operation2 addExecutionBlock:^() {
    NSLog(@"3:NSBlockOperation:%@", [NSThread currentThread]);
}];

[operation2 addExecutionBlock:^() {
    NSLog(@"4:NSBlockOperation:%@", [NSThread currentThread]);
}];

[operation2 addExecutionBlock:^() {
    NSLog(@"5:NSBlockOperation:%@", [NSThread currentThread]);
}];  

[queue addOperation:operation1];
[queue addOperation:operation2];



- (void)run {
    NSLog(@"1:NSInvocationOperation:%@", [NSThread currentThread]);
}

结果:

**2016-07-06 11:03:15.197 ****类库****[6736:2840181] 1:NSInvocationOperation****:****<NSThread: 0x16542de0>{number = 2, name = (null)}**
**2016-07-06 11:03:15.198 ****类库****[6736:2840176] 2:NSBlockOperation****:****<NSThread: 0x16521a80>{number = 3, name = (null)}**
**2016-07-06 11:03:15.198 ****类库****[6736:2840176] 3:NSBlockOperation****:****<NSThread: 0x16521a80>{number = 3, name = (null)}**
**2016-07-06 11:03:15.198 ****类库****[6736:2840176] 4:NSBlockOperation****:****<NSThread: 0x16521a80>{number = 3, name = (null)}**
**2016-07-06 11:03:15.200 ****类库****[6736:2840176] 5:NSBlockOperation****:****<NSThread: 0x16521a80>{number = 3, name = (null)}**

可以看出任务是异步并发执行的

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容