码迷,mamicode.com
首页 > 其他好文 > 详细

NSOperation && NSOperationQueue使用

时间:2015-05-10 23:49:01      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:

NSOperation&&NSOperationQueue使用

NSOperation

用来封装我们想要异步执行的任务(下载图片/图片滤镜操作), NSOperation 是一个抽象类,与 NSNumber 是一样,本身并没有多少的用途,不能向 NSOperationQueue 中添加操作。有用的是它的子类


NSInvocationOperation

继承自 NSOperation 的子类,能将一个方法成封装任务,并提交给NSOperationQueue 调度

同步执行

1 NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:@"invocation"];
2 [invocationOperation start];

 

在这里创建了一个 NSInvocationOperation 对象, NSInvocationOperation 将一个方法(doSomething:)添加到操作中,然后我们直接调用了 start 方法,调用这个方法后,doSomething: 方法中的任务会在当前线程中同步执行

异步执行

1 NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:@"invocation"];
2 
3 NSOperationQueue *queue = [[NSOperationQueue alloc] init];
4 
5 [queue addOperation:invocationOperation];

 

同样创建了一个 NSInvocationOperation 对象, NSInvocationOperation 将一个方法(doSomething:)添加到操作中,在方法中做我们想要异步的任务,然后再交给队列去调度,会在子线程中执行 (object参数是给doSomething:传递参数)


NSBlockOperation

同样是继承自 NSOperation 的子类,能将多个 block 添加到操作中,提交给 NSOperationQueue 调度

同步执行

1 NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
2 
3   // 任务A
4 
5 }];
6 
7 [blockOperation start];

 

用类方法创建一个 NSBlockOperation 对象,并向操作中添加任务,调用 start 方法,在当前线程同步执行

异步执行

 1 NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
 2 
 3   // 任务A
 4 
 5 }];
 6 
 7 [blockOperation addExecutionBlock:^{
 8 
 9   // 任务B
10 
11 }];
12 
13 [blockOperation addExecutionBlock:^{
14 
15   // 任务C
16 
17 }];
18 
19 [blockOperation start];

 

我们在创建完 NSBlockOperation 后,还可以在向 operation 中添加任务,在这种情况下,系统会自动为我们开启新的线程异步执行所有的任务

提交给队列的异步执行

1 NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
2 
3   // 任务A
4 
5 }];
6 
7 NSOperationQueue *queue = [[NSOperationQueue alloc] init];
8 
9 [queue addOperation:blockOperation];

 

创建一个 NSBlockOperation 对象并添加任务,之后提交给队列异步执行,这种情况下系统也会自动为我们开启子线程,然后在子线程中异步执行任务

自定义Operation

有时系统给我们提供的 Operation 并不好用,这时我们就需要做自己定义 Operation

  1. 建立一个类(例如:NSDownloadImageOperation)继承自 NSOperation
  2. 重写 NSDownloadImageOperation 中的 main 方法,在 main 方法中实现我们想要的执行任务
  3. 在 main 方法中自己创建自动释放池,因为如果是异步操作的话,就无法访问主线程中的自动释放池
  4. 可能操作会被停止,所以我们要在 main 方法中经常通过 isCancelled 方法判断是否操作被停止,然后做出相应的响应

其它属性

Operation 有一个 completionBlock 属性,用来监听 Operation 操作完成后,需要执行操作


NSOperationQueue: 调度提交的 Operation

1. 将 Operation 添加给队列

 1 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 2 3 [queue addOperation:operation]; 

2. 直接给队列添加 block 任务

1 NSOperationQueue *queue = [[NSOperationQueue alloc] init];
2 
3 [queue addOperationWithBlock:^{
4 
5   // 任务
6 
7 }];

 

3. 队列的最大并发数: 在同一时间,能有多少条线程执行操作用 maxConcurrentOperationCount 属性设置最大并发数

 1 NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
 2 
 3   for (int i = 0; i < 3; ++i) {
 4 
 5     [NSThread sleepForTimeInterval:.001];
 6 
 7     NSLog(@"%@", [NSThread currentThread]);
 8 
 9   }
10 
11 }];
12 
13 NSOperationQueue *queue = [[NSOperationQueue alloc] init];
14 
15 [queue addOperation:blockOperation];
16 
17 [queue addOperationWithBlock:^{
18 
19   for (int i = 0; i < 3; ++i) {
20 
21     [NSThread sleepForTimeInterval:.001];
22 
23     NSLog(@"%@", [NSThread currentThread]);
24 
25   }
26 
27 }];
28 
29 queue.maxConcurrentOperationCount = 2;

 

技术分享

由上面的结果,我们可以得到在同意时间最大并发线程的条数是2,尽管线程 number 已经开到3

 

4. 队列的取消

通过 cancelAllOperations 方法取消所有的Operation

 

5. 队列的挂起与回复

通过 setSuspended: 方法将队列挂起(YES)、恢复(NO)

 

6. 操作之间的先后顺序: NSOperation之间可以设置依赖来保证执行顺序

 1 [operationB addDependency:operationA]; // 操作B依赖于操作A, 操作A在操作B之前执行

还可以在不同queue的NSOperation之间创建依赖关系

技术分享

执行顺序: Operation B -> Operation 1 -> Operation 2 -> Operation C -> Operation 3 -> Operation D

Operation A 与 Operation 4 异步执行

NSOperation && NSOperationQueue使用

标签:

原文地址:http://www.cnblogs.com/yys-lzh/p/4493189.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!