zoukankan      html  css  js  c++  java
  • GCD学习之dispatch_barrier_async

        iOS常见的多线程开发方式有NSThread、NSOPeration和GCD,抽象程度依次提高,GCD是最抽象的,使用起来最简单,但相对来说功能有限,比如不能cancel任务,这也算是一点遗憾吧。

        今天主要记录下学习dispatch_barrier_async中遇到的问题(其实是自己没仔细看Apple文档),dispatch_barrier_async是在执行完前面的任务后它才执行,而且它后面的任务等它执行完成之后才会执行(先后顺序是按照添加到queue的次序),但该API适用的场景是dispatch queue必须是用DISPATCH_QUEUE_CONCURRENT属性创建的queue,而不能是用系统定义好的dispatch_get_global_queue,下面是测试代码:

    1、当dispatch queue是dispatch_get_global_queue时,dispatch_barrier_async失效:

     1 - (void)viewDidLoad {
     2     [super viewDidLoad];
     3     // Do any additional setup after loading the view, typically from a nib.
     4     NSLog(@"main thread:%p",[NSThread currentThread]);
     5     [self testBarrierBlockWithGlobalQueue];
     6 }
     7 - (void)testBarrierBlockWithGlobalQueue
     8 {
     9     NSLog(@"current iOS Version:%.1f",[[[UIDevice currentDevice] systemVersion] floatValue]);
    10     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    11     dispatch_async(queue, ^{
    12         [NSThread sleepForTimeInterval:2];
    13         NSLog(@"Excute block 1:%p",[NSThread currentThread]);
    14     });
    15     dispatch_async(queue, ^{
    16         [NSThread sleepForTimeInterval:3];
    17         NSLog(@"Excute block 2:%p",[NSThread currentThread]);
    18     });
    19     dispatch_barrier_async(queue, ^{
    20         NSLog(@"Excute block 3:%p",[NSThread currentThread]);
    21         [NSThread sleepForTimeInterval:4];
    22     });
    23     dispatch_async(queue, ^{
    24         NSLog(@"Excute block 4:%p",[NSThread currentThread]);
    25     });
    26 }
    27 打印结果:
    28 2015-06-09 23:16:33.799 testGCD[46920:3369866] main thread:0x7f87f8c0af70
    29 2015-06-09 23:16:33.800 testGCD[46920:3369866] current iOS Version:8.3
    30 2015-06-09 23:16:33.800 testGCD[46920:3370037] Excute block 4:0x7f87f8e14a60
    31 2015-06-09 23:16:33.800 testGCD[46920:3370029] Excute block 3:0x7f87f8f222d0
    32 2015-06-09 23:16:35.802 testGCD[46920:3370027] Excute block 1:0x7f87f8f27a90
    33 2015-06-09 23:16:36.804 testGCD[46920:3370026] Excute block 2:0x7f87f8c1e610

    从打印结果可以看到不是预想的block3在block1、block2后面,最后再执行block4,说明在global_queue下dispatch_barrier_async失效。

    2、当dispatch queue是用DISPATCH_QUEUE_CONCURRENT属性创建的queue时,dispatch_barrier_async有效:

     1 - (void)testBarrierBlockWithCreateQueue
     2 {
     3     NSLog(@"current iOS Version:%.1f",[[[UIDevice currentDevice] systemVersion] floatValue]);
     4     dispatch_queue_t queue = dispatch_queue_create("com.testBarrierGCD", DISPATCH_QUEUE_CONCURRENT);
     5     dispatch_async(queue, ^{
     6         [NSThread sleepForTimeInterval:2];
     7         NSLog(@"Excute block 1:%p",[NSThread currentThread]);
     8     });
     9     dispatch_async(queue, ^{
    10         [NSThread sleepForTimeInterval:3];
    11         NSLog(@"Excute block 2:%p",[NSThread currentThread]);
    12     });
    13     dispatch_barrier_async(queue, ^{
    14         NSLog(@"Excute block 3:%p",[NSThread currentThread]);
    15         [NSThread sleepForTimeInterval:4];
    16     });
    17     dispatch_async(queue, ^{
    18         NSLog(@"Excute block 4:%p",[NSThread currentThread]);
    19     });
    20 }
    21 打印结果:
    22 2015-06-09 23:21:55.671 testGCD[46963:3373180] main thread:0x7fa51a428130
    23 2015-06-09 23:21:55.672 testGCD[46963:3373180] current iOS Version:8.3
    24 2015-06-09 23:21:57.676 testGCD[46963:3373293] Excute block 1:0x7fa51a65a890
    25 2015-06-09 23:21:58.673 testGCD[46963:3373294] Excute block 2:0x7fa51a71cf50
    26 2015-06-09 23:21:58.674 testGCD[46963:3373294] Excute block 3:0x7fa51a71cf50
    27 2015-06-09 23:22:02.676 testGCD[46963:3373294] Excute block 4:0x7fa51a71cf50

    从打印结果可以看出block执行顺序是按照我们预期的顺序在执行,至此说明了dispatch_barrier_async适用的场景是dispatch queue必须是用DISPATCH_QUEUE_CONCURRENT属性创建的queue(其实Apple文档中有说明的,以后用新的API时一定得仔细阅读文档,避免多走弯路)~祝大家玩的愉快~

    测试代码已上传至GitHub:https://github.com/iOSGeek0829/testGCDWithBarrierBlock

  • 相关阅读:
    <<剪绳子>>题解
    P5743 小猴吃桃 题解
    注意C++中的int与long long 的乘法
    数组初始化方法总结
    一维差分和二维差分
    一维前缀和与二维前缀和
    例2-6 字母转换
    例1-11 评测机队列
    golang ---查找字串实例 IP address
    mongodb ---加减等操作
  • 原文地址:https://www.cnblogs.com/NerdFooProgrammer/p/4564961.html
Copyright © 2011-2022 走看看