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,实现内部相应的⽅法

二、 具体说明

1.NSInvocationOperation子类

创建对象和执行操作:

1
2
3
4
5
//创建操作对象,封装要执行的任务
//NSInvocationOperation   封装操作
  NSInvocationOperation *operation=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test) object:nil];
//执行操作
  [operation start];

说明:一旦执⾏操作,就会调用target的test方法

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//  YYViewController.m
//  01-NSOperation基本1
 #import "YYViewController.h"
 @interface YYViewController ()
 @end
 @implementation YYViewController
 - (void)viewDidLoad{
    [super viewDidLoad];
    //NSOperation:抽象类,不具备封装功能    
    //创建操作对象,封装要执行的任务
    //NSInvocationOperation   封装操作
      NSInvocationOperation *operation=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test) object:nil];  
    //执行操作
     [operation start];
 }
 -(void)test {
    NSLog(@"--test--%@--",[NSThread currentThread]);
  }
 @end

打印查看:

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

2.NSBlockOperation子类

创建对象和添加操作:

1
2
3
4
5
6
7
8
//创建NSBlockOperation操作对象
  NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{
//......
  }];
//添加操作
 [operation addExecutionBlock:^{
       //....
 }];

代码示例:

代码1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
YYViewController.m
 #import "YYViewController.h"
 @interface YYViewController ()
 @end
 @implementation YYViewController
- (void)viewDidLoad {
   [super viewDidLoad];   
  //创建NSBlockOperation操作对象
    NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{
      NSLog(@"NSBlockOperation------%@",[NSThread currentThread]);
    }];    
  //开启执行操作
  [operation start];
  }
@end

打印查看:

代码2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
YYViewController.m
 #import "YYViewController.h"
 @interface YYViewController ()
 @end
 @implementation YYViewController
- (void)viewDidLoad {
   [super viewDidLoad];   
    //创建NSBlockOperation操作对象
    NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{
       NSLog(@"NSBlockOperation------%@",[NSThread currentThread]);
    }];   
   //添加操作
    [operation addExecutionBlock:^{
       NSLog(@"NSBlockOperation1------%@",[NSThread currentThread]);
    }];  
    [operation addExecutionBlock:^{
        NSLog(@"NSBlockOperation2------%@",[NSThread currentThread]);
    }];    
   //开启执行操作
   [operation start];
  }
 @end

注意:只要NSBlockOperation封装的操作数 > 1,就会异步执行操作 

3.NSOperationQueue

NSOperationQueue的作⽤:NSOperation可以调⽤start⽅法来执⾏任务,但默认是同步执行的

如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会自动异步执行NSOperation中的操作

添加操作到NSOperationQueue中,自动执行操作,自动开启线程

1
2
3
4
5
6
7
8
9
10
11
//创建NSOperationQueue
  NSOperationQueue * queue=[[NSOperationQueue alloc]init];
//把操作添加到队列中
//第一种方式
  [queue addOperation:operation1];
  [queue addOperation:operation2];
  [queue addOperation:operation3];
//第二种方式
  [queue addOperationWithBlock:^{
     NSLog(@"NSBlockOperation3--4----%@",[NSThread currentThread]);
  }];

 - (void)addOperation:(NSOperation *)op;

- (void)addOperationWithBlock:(void (^)(void))block; 

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
YYViewController.m
  #import "YYViewController.h"
  @interface YYViewController ()
  @end
  @implementation YYViewController
  - (void)viewDidLoad {
     [super viewDidLoad];
      //创建NSInvocationOperation对象,封装操作
      NSInvocationOperation *operation1=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test1) object:nil];
      NSInvocationOperation *operation2=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test2) object:nil];
      //创建对象,封装操作
      NSBlockOperation *operation3=[NSBlockOperation blockOperationWithBlock:^{
          NSLog(@"NSBlockOperation3--1----%@",[NSThread currentThread]);
      }];
     [operation3 addExecutionBlock:^{
         NSLog(@"NSBlockOperation3--2----%@",[NSThread currentThread]);
     }];
     
     //创建NSOperationQueue
     NSOperationQueue * queue=[[NSOperationQueue alloc]init];
     //把操作添加到队列中
     [queue addOperation:operation1];
     [queue addOperation:operation2];
     [queue addOperation:operation3];
 }
-(void)test1 {
    NSLog(@"NSInvocationOperation--test1--%@",[NSThread currentThread]);
 }
-(void)test2 {
    NSLog(@"NSInvocationOperation--test2--%@",[NSThread currentThread]);
 }
@end

打印效果:

注意:系统自动将NSOperationqueue中的NSOperation对象取出,将其封装的操作放到一条新的线程中执行。上面的代码示例中,一共有四个任务,operation1和operation2分别有一个任务,operation3有两个任务。一共四个任务,开启了四条线程。通过任务执行的时间全部都是273可以看出,这些任务是并行执行的。

提示:队列的取出是有顺序的,与打印结果并不矛盾。这就好比,选手A,BC虽然起跑的顺序是先A,后B,然后C,但是到达终点的顺序却不一定是A,B在前,C在后。

下面使用for循环打印,可以更明显的看出任务是并发执行的。

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#import "YYViewController.h"
@interface YYViewController ()
@end
@implementation YYViewController
- (void)viewDidLoad {
    [super viewDidLoad];
     //创建NSInvocationOperation对象,封装操作
     NSInvocationOperation *operation1=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test1) object:nil];
     NSInvocationOperation *operation2=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test2) object:nil];
     //创建对象,封装操作
     NSBlockOperation *operation3=[NSBlockOperation blockOperationWithBlock:^{
        for (int i=0; i<5; i++) {
            NSLog(@"NSBlockOperation3--1----%@",[NSThread currentThread]);
         }
      }];
     [operation3 addExecutionBlock:^{
         for (int i=0; i<5; i++) {
          NSLog(@"NSBlockOperation3--2----%@",[NSThread currentThread]);
         }
      }];    
   //创建NSOperationQueue
    NSOperationQueue * queue=[[NSOperationQueue alloc]init];
   //把操作添加到队列中
   [queue addOperation:operation1];
   [queue addOperation:operation2];
   [queue addOperation:operation3];
  }
 -(void)test1 {
     for (int i=0; i<5; i++) {
      NSLog(@"NSInvocationOperation--test1--%@",[NSThread currentThread]);
     }
  }
 -(void)test2 {
      for (int i=0; i<5; i++) {
       NSLog(@"NSInvocationOperation--test2--%@",[NSThread currentThread]);
    }
   }
 @end

posted on   梁飞宇  阅读(170)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示