1. 需求:
    有两个任务都要放在子线程中执行, 且要保证A执行完再执行B.
    如果你也有同样的需求, 可以从下面几种方法中挑选一种

  1. 实现方法
    1.1. 方法一 使用GCD串行队列. 先创建一个串行队列, 将任务加入到串行队列中, 因为是串行队列,能保证顺序执行, 且因为是串行队列,所以两个任务是在同一线程执行.
   dispatch_queue_t queue = dispatch_queue_create("myCostom", DISPATCH_QUEUE_SERIAL);NSLog(@"dispatch111 start");dispatch_async(queue, ^{NSLog(@"sleep1111");NSLog(@"dispatch111 %@", [NSThread currentThread]);[NSThread sleepForTimeInterval:5];NSLog(@"awake up111");});NSLog(@"dispatch2222 start");dispatch_async(queue, ^{NSLog(@"sleep 2222");NSLog(@"dispatch2222 %@", [NSThread currentThread]);[NSThread sleepForTimeInterval:5];NSLog(@"awake up222222");});NSLog(@"dispatch 33333");

1.2 方法二 使用barrier.

   dispatch_queue_t queue = dispatch_queue_create("mycustom", DISPATCH_QUEUE_CONCURRENT);NSLog(@"dispatch111 start");dispatch_async(queue, ^{NSLog(@"sleep1111");NSLog(@"dispatch111 %@", [NSThread currentThread]);[NSThread sleepForTimeInterval:5];NSLog(@"awake up111");});dispatch_barrier_async(queue, ^{NSLog(@"------------------- barrier");});NSLog(@"dispatch2222 start");dispatch_async(queue, ^{NSLog(@"sleep 2222");NSLog(@"dispatch2222 %@", [NSThread currentThread]);[NSThread sleepForTimeInterval:5];NSLog(@"awake up222222");});NSLog(@"dispatch 33333");

打印结果

2017-07-18 16:42:48.866 Test[4336:640379] dispatch111 start
2017-07-18 16:42:48.866 Test[4336:640379] dispatch2222 start
2017-07-18 16:42:48.866 Test[4336:640550] sleep1111
2017-07-18 16:42:48.866 Test[4336:640379] dispatch 33333
2017-07-18 16:42:48.866 Test[4336:640550] dispatch111 <NSThread: 0x60000026f700>{number = 3, name = (null)}
2017-07-18 16:42:53.869 Test[4336:640550] awake up111
2017-07-18 16:42:53.870 Test[4336:640550] ------------------- barrier
2017-07-18 16:42:53.870 Test[4336:640550] sleep 2222
2017-07-18 16:42:53.870 Test[4336:640550] dispatch2222 <NSThread: 0x60000026f700>{number = 3, name = (null)}
2017-07-18 16:42:58.872 Test[4336:640550] awake up222222

^^^^
重点 你可以观察到 先打印了dispatch 333 在打印 barrier, 说明barrier 阻塞的不是barrier所在的线程,而是queue所在的线程

重点如果我把 dispatch_barrier_async 换成 dispatch_barrier_sync 这就连当前线程也阻塞了

1.3 方法三 使用NSOperation
在这之前简单介绍一下 NSOperation
* NSOperation 是对GCD的封装.
* NSOperation 是一个抽象类, 不能封装任务, 需要他的两个子类完成 NSInvocationOperationNSBlockOperation
* 需要调用start 方法开启, 默认是同步执行,也就是说默认不会开线程, 也可以使用 cancel 方法取消, 但是只能取消未开始的任务,已经开始的任务,无法被取消.
* 在NSOperation 添加到queue后, 通常会在很短的时间内得到运行, 但是如果Operation有添加依赖或者queue 被设置成等待, 那可能需要等待.

结合最后一条, 所以我们现在来使用依赖实现我们的需求.

 NSOperationQueue * queue = [[NSOperationQueue alloc] init];NSBlockOperation * op1 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"sleep1111");NSLog(@"dispatch111 %@", [NSThread currentThread]);[NSThread sleepForTimeInterval:5];NSLog(@"awake up111");}];NSBlockOperation * op2 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"sleep 2222");NSLog(@"dispatch2222 %@", [NSThread currentThread]);[NSThread sleepForTimeInterval:5];NSLog(@"awake up222222");}];[op1 addDependency:op2];[queue addOperation:op1];[queue addOperation:op2];

1.4 方法四, 既然NSOperation是对GCD的封装,那么联想方法一, 我想能不能将NSOperationQueue也设置成串行队列.
但是NSOperationQueue好像屏蔽了这个串行并行这个概念, 而是使用 queue.maxConcurrentOperationCount 来设置queue一次能够执行的任务量.
如果设置成1. 就类似于串行队列, 任务会 顺序执行 . 但是只是类似, 因为在串行队列 + 异步执行时,会开辟一条子线程. 但是将maxConcurrentOperationCount 设置成1后, 有可能会开辟多条线程,也就是说, 任务一和任务二可能会在同一线程上执行, 也可能在不同线程上执行.

  NSOperationQueue *queue = [[NSOperationQueue alloc] init];queue.maxConcurrentOperationCount = 1;NSLog(@"NSOperation111 start");NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"sleep1111");NSLog(@"NSOperation111 %@", [NSThread currentThread]);[NSThread sleepForTimeInterval:3];NSLog(@"awake up111");}];NSLog(@"NSOperation2222 start");NSInvocationOperation *operationI = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(testInvocaionOperatation) object:nil];[queue addOperation:operationB];[queue addOperation:operationI];NSLog(@"NSOperation 33333")

打印结果

2017-07-18 19:13:56.971 Test[4691:708449] NSOperation111 start
2017-07-18 19:13:56.972 Test[4691:708449] NSOperation2222 start
2017-07-18 19:13:56.972 Test[4691:708449] NSOperation 33333
2017-07-18 19:13:56.972 Test[4691:708483] sleep1111
2017-07-18 19:13:56.973 Test[4691:708483] NSOperation111 <NSThread: 0x60800026e200>{number = 3, name = (null)}
2017-07-18 19:14:00.048 Test[4691:708483] awake up111
2017-07-18 19:14:00.049 Test[4691:708481] sleep 2222
2017-07-18 19:14:00.049 Test[4691:708481] NSOperation2222 <NSThread: 0x60800026e800>{number = 4, name = (null)}
2017-07-18 19:14:03.110 Test[4691:708481] awake up222222

观察可知, 当前两个任务没有在同一线程上执行,但是sleep222 和awake up222都是在 awake111后执行的, 也即是说是顺序执行.

以上四种方式, 经过我测 试, 应该是都能实现我的需求, 如果有不对的地方, 请多多指教
联系方式 QQ 2711056454

iOS 控制任务执行顺序相关推荐

  1. jmeter控制请求执行顺序

    一.同一个线程组内可通过jmeter-Critical Section Controller (临界部分控制器)来控制 业务逻辑: 根据锁名来控制并发,同一个锁名之下,在同一时间点只能存在一个运行中, ...

  2. java 控制线程的顺序_【Java多线程系列四】控制线程执行顺序

    packagecom.concurrent.test;importjava.util.concurrent.CountDownLatch;importorg.junit.Assert;importor ...

  3. unittest控制case执行顺序

    1.名字改成test_a_xxx, test_b_xxx格式,会分别执行a, b, .... 2.     suite = unittest.TestSuite()     suite.addTest ...

  4. UIViewController的生命周期及iOS程序执行顺序

    当一个视图控制器被创建,并在屏幕上显示的时候. 代码的执行顺序 1. alloc                                   创建对象,分配空间 2.init (initWit ...

  5. java注解的执行顺序_深入理解Spring的@Order注解和Ordered接口

    前言 Spring的@Order注解或者Ordered接口大家都知道是控制顺序的,那么它们到底是控制什么顺序的?是控制Bean的注入顺序,还是Bean的实例化顺序,还是Bean的执行顺序呢?那么我们先 ...

  6. 如何改变 Python 中线程的执行顺序

    一.主线程会等待所有的子线程结束后才结束 首先我看下最普通情况下,主线程和子线程的情况. import threading from time import sleep, ctimedef sing( ...

  7. java 过滤器执行图_「filterchain」java 过滤器Filter中chain.doFilter()之前和之后代码的执行顺序 - seo实验室...

    filterchain 过滤器拦截到请求之后,首先是执行doFilter()方法中chain.doFilter()之前的代码,然后放弃权限给下一个过滤器或者serverlet等等,最后才执行chain ...

  8. 【青少年编程】【答疑】控制Scratch异步代码的执行顺序

    问题 几天前,我写了一篇图文 对「等待(0)秒」的理解,发现可以利用「等待(0)秒」这个积木块来解决Scratch中异步代码的执行顺序问题,即点击绿旗后可以控制多个角色中响应该事件的代码的顺序. 在这 ...

  9. iOS tableview的常用delegate和dataSource执行顺序

    在这次项目中遇到了一个特别奇葩的问题:表视图创建的cell在7以上的系统能正常运行显示,在模拟器上就不能正常实现......为解决这个问题,纠结了好久...... 对在7系统上不显示的猜测: 用mas ...

最新文章

  1. Excel Services的配置与使用(图解)
  2. Neutron Router 工作原理 - 每天5分钟玩转 OpenStack(142)
  3. Python学习之路—2018/7/14
  4. 架构设计贵在务实(转载)
  5. mysql使用数据库_MySQL数据库的常用操作
  6. (转)OpenLayers3基础教程——OL3基本概念
  7. hadoop 命令行相关操作
  8. 如何看待 Kotlin 成为 Android 官方支持开发语言?
  9. KEIL软件安装教程
  10. Android设备研发术语表
  11. [管理员手册](五)Ubuntu desktop 20.04系统安装显卡驱动NVIDIA cuda pytorch向日葵sunlogin安装
  12. kelley c语言教程 机械工业出版社,北京工业大学2020年考研893软件工程学科专业基础考试大纲...
  13. 构建Android Push Notification Service服务端及客户端
  14. 产品读书《数据产品经理必修课:从零经验到令人惊艳》别读了!!!
  15. Android和OpenCV的学习mat运算/颜色转换
  16. Linux学习2.0(非markdown编辑)
  17. Xiaojie雷达之路---雷达原理(二刷)相位法测角
  18. 百病之源五脏为根(国粹---gt;中医;在此提倡自然疗法!)
  19. 布置主卧室的八大风水要点
  20. 【激光slam仿真】启动gazebo仿真环境报错[spawn_model-4] process has died

热门文章

  1. AIX 上总有一种压缩方式适合你
  2. 编码的奥秘:手电筒剖析
  3. 微信吸粉实战二:腾讯新闻
  4. 英语作文框架(四级)
  5. SAP 汇率处理总结
  6. mysqli assoc php,关于php:mysqli_fetch_assoc()期望参数1为mysqli_result,给定布尔值
  7. 前后台处理得到 前台图片 draw.io/ mxgraph
  8. 网园网络电视 v1.2 官方
  9. AI医学影像千亿长坡,“医疗AI第一股”鹰瞳科技为何能滚起雪球?
  10. 电脑快捷修改计算机名