设为首页 加入收藏

TOP

iOS 多线程 NSOperation、NSOperationQueue(四)
2019-08-31 00:20:48 】 浏览:115
Tags:iOS 线程 NSOperation NSOperationQueue
OperationQueue alloc] init]; // 2.设置最大并发操作数 queue.maxConcurrentOperationCount = 1; // 串行队列 // queue.maxConcurrentOperationCount = 2; // 并发队列 // queue.maxConcurrentOperationCount = 8; // 并发队列 // 3.添加操作 [queue addOperationWithBlock:^{ for (int i = 0; i < 2; i++) { [NSThread sleepForTimeInterval:2]; // 模拟耗时操作 NSLog(@"1---%@", [NSThread currentThread]); // 打印当前线程 } }]; [queue addOperationWithBlock:^{ for (int i = 0; i < 2; i++) { [NSThread sleepForTimeInterval:2]; // 模拟耗时操作 NSLog(@"2---%@", [NSThread currentThread]); // 打印当前线程 } }]; [queue addOperationWithBlock:^{ for (int i = 0; i < 2; i++) { [NSThread sleepForTimeInterval:2]; // 模拟耗时操作 NSLog(@"3---%@", [NSThread currentThread]); // 打印当前线程 } }]; [queue addOperationWithBlock:^{ for (int i = 0; i < 2; i++) { [NSThread sleepForTimeInterval:2]; // 模拟耗时操作 NSLog(@"4---%@", [NSThread currentThread]); // 打印当前线程 } }]; }
  • 最大并发操作数为1 输出结果:


     
     
  • 最大并发操作数为2 输出结果:


     
     
  • 可以看出:当最大并发操作数为1时,操作是按顺序串行执行的,并且一个操作完成之后,下一个操作才开始执行。当最大操作并发数为2时,操作是并发执行的,可以同时执行两个操作。而开启线程数量是由系统决定的,不需要我们来管理。

这样看来,是不是比 GCD 还要简单了许多?

6. NSOperation 操作依赖

NSOperation、NSOperationQueue 最吸引人的地方是它能添加操作之间的依赖关系。通过操作依赖,我们可以很方便的控制操作之间的执行先后顺序。NSOperation 提供了3个接口供我们管理和查看依赖。

  • - (void)addDependency:(NSOperation *)op;添加依赖,使当前操作依赖于操作 op 的完成。
  • - (void)removeDependency:(NSOperation *)op;移除依赖,取消当前操作对操作 op 的依赖。
  • @property (readonly, copy) NSArray<NSOperation *> *dependencies;在当前操作开始执行之前完成执行的所有操作对象数组。

当然,我们经常用到的还是添加依赖操作。现在考虑这样的需求,比如说有 A、B 两个操作,其中 A 执行完操作,B 才能执行操作。

如果使用依赖来处理的话,那么就需要让操作 B 依赖于操作 A。具体代码如下:

/** * 操作依赖 * 使用方法:addDependency: */ - (void)addDependency { // 1.创建队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 2.创建操作 NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{ for (int i = 0; i < 2; i++) { [NSThread sleepForTimeInterval:2]; // 模拟耗时操作 NSLog(@"1---%@", [NSThread currentThread]); // 打印当前线程 } }]; NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{ for (int i = 0; i < 2; i++) { [NSThread sleepForTimeInterval:2]; // 模拟耗时操作 NSLog(@"2---%@", [NSThread currentThread]); // 打印当前线程 } }]; // 3.添加依赖 [op2 addDependency:op1]; // 让op2 依赖于 op1,则先执行op1,在执行op2 // 4.添加操作到队列中 [queue addOperation:op1]; [queue addOperation:op2]; } 

输出结果:


 
 
  • 可以看到:通过添加操作依赖,无论运行几次,其结果都是 op1 先执行,op2 后执行。

7. NSOperation 优先级

NSOperation 提供了queuePriority(优先级)属性,queuePriority属性适用于同一操作队列中的操作,不适用于不同操作队列中的操作。默认情况下,所有新创建的操作对象优先级都是NSOperationQueuePriorityNormal。但是我们可以通过setQueuePriority:方法来改变当前操作在同一队列中的执行优先级。

// 优先级的取值 typedef NS_ENUM(NSInteger, NSOperationQueuePriority) { NSOperationQueuePriorityVeryLow = -8L, NSOperationQueuePriorityLow = -4L, NSOperationQueuePriorityNormal = 0, NSOperationQueuePriorityHigh = 4, NSOperationQueuePriorityVeryHigh = 8 }; 

上边我们说过:对于添加到队列中的操作,首先进入准备就绪的状态(就绪状态取决于操作之间的依赖关系),然后进入就绪状态的操作的开始执行顺序(非结束执行顺序)由操作之间相对的优先级决定(优先级是操作对象自身的属性)。

那么,什么样的操作才是进入就绪状态的操作呢?

  • 当一个操作的所有依赖都已经完成时,操作对象通常会进入准备就绪状态,等待执行。

举个例子,现在有4个优先级都是 NSOperationQueuePriorityNormal(默认级别)的操作:op1,op2,op3,op4。其中 op3 依赖于 op2,op2 依赖于 op1,即 op3 -> op2 -> op1。现在将这4个操作添加到队列中并发执行。

  • 因为 op1 和 op4 都没有需要依赖的操作,所以在 op1,op4 执行之前,就是处于准备就绪状态的操作。
  • 而 op3 和 op2 都有依赖的操作(op3 依赖于 op2,op2 依赖于 op1),所以 op3 和 op2 都不是准备就绪状态下的操作。
首页 上一页 1 2 3 4 5 6 下一页 尾页 4/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇[iOS]异常捕捉 下一篇ipa的plist文件查看

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目