iOS--GCD(二)

来源:互联网 发布:mysql 建库 utf8 编辑:程序博客网 时间:2024/05/16 14:31

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="font-size:14px;">上一篇中,我们可以了解到GCD关于串行、并行最基本的用法,接下来我们来了解下GCD其他方面的功能。</span></span>


延迟执行 after

<span style="font-size:14px;">double delayInSeconds = 3.0;dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));    //serial queuedispatch_after(popTime, dispatch_get_main_queue(), ^(void){        NSLog(@"hello gcd,这里是serial queue");    });    //concurrent queuedispatch_queue_t myConcurrentQueue = dispatch_queue_create("com.xiaolan.GCD.myConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);dispatch_after(popTime, myConcurrentQueue, ^(void){        NSLog(@"hello gcd,这里是concurrent queue");    });</span>

使用dispatch_after函数将延迟执行某个任务,既可以在serial queue中使用,也可以在concurrent queue中使用。


组执行后再执行 group

<span style="font-size:14px;">//创建groupdispatch_group_t group = dispatch_group_create();    dispatch_queue_t myConcurrentQueue = dispatch_queue_create("com.xiaolan.GCD.myConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);    //dispatch_group_async用于把不同的任务归为一组dispatch_group_async(group, myConcurrentQueue, ^{        NSLog(@"任务1,线程%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);    });dispatch_group_async(group, myConcurrentQueue, ^{        NSLog(@"任务2,线程%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);    });dispatch_group_async(group, myConcurrentQueue, ^{        NSLog(@"任务3,线程%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);    });//dispatch_group_notify当指定组的任务执行完毕之后,执行给定的任务dispatch_group_notify(group, myConcurrentQueue, ^{        NSLog(@"group中的任务都执行完毕之后,执行此任务。所在线程%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);    });</span>

打印结果:



一堵墙 barrier

    访问数据时为了保证安全,一般使用serial queue,但是serial queue却有着任务一个执行完毕后再执行下一个任务的缺陷。

    在访问数据库的时候,serial queue适用于写入任务,保证数据安全,concurrent queue适用于读取任务,保证速度与效率。

    但是数据库的访问,读取与写入大多时候是同时操作的,此时该如何处理好这种关系成为了关键问题,GCD给了我们一个很好的解决方法—barrier。


<span style="font-size:14px;">dispatch_queue_t myConcurrentQueue = dispatch_queue_create("com.xiaolan.GCD.myConcurrentQueue", DISPATCH_QUEUE_CONCURRENT); //开始读取操作dispatch_async(myConcurrentQueue, ^{        NSLog(@"读取数据A,线程%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);    });dispatch_async(myConcurrentQueue, ^{        NSLog(@"读取数据B,线程%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);    });dispatch_async(myConcurrentQueue, ^{        NSLog(@"读取数据C,线程%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);    });dispatch_async(myConcurrentQueue, ^{        NSLog(@"读取数据D,线程%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);    });    //开始写入操作dispatch_barrier_async(myConcurrentQueue, ^{        NSLog(@"写入数据K,线程%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);    });dispatch_barrier_async(myConcurrentQueue, ^{        NSLog(@"写入数据L,线程%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);    });dispatch_barrier_async(myConcurrentQueue, ^{        NSLog(@"写入数据O,线程%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);    });dispatch_barrier_async(myConcurrentQueue, ^{        NSLog(@"写入数据P,线程%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);    });  //开始读取操作dispatch_async(myConcurrentQueue, ^{        NSLog(@"读取数据E,线程%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);    });    dispatch_async(myConcurrentQueue, ^{        NSLog(@"读取数据F,线程%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);    });dispatch_async(myConcurrentQueue, ^{        NSLog(@"读取数据G,线程%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);    });dispatch_async(myConcurrentQueue, ^{        NSLog(@"读取数据H,线程%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);    });</span>

打印结果:



     dispatch_barrier_async就像一道墙,之前的任务都并行执行,执行完毕之后,执行barrier中的任务,打印结果中可以从number的数值看出barrier中得任务都是在一个线程中按顺序执行完毕的,之后的任务是并行执行。


重复 apply


<span style="font-size:14px;">NSArray *array = [NSArray arrayWithObjects:@"A",@"B",@"C",@"D", nil];    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);dispatch_apply([array count], queue, ^(size_t index) {        NSLog(@"%@所在线程%@,是否是主线程:%d",[array objectAtIndex:index], [NSThread currentThread],[[NSThread currentThread] isMainThread]);    });</span>


只执行一次 once


<span style="font-size:14px;">static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        NSLog(@"只执行一次");    });</span>


经常用于单例的实现







0 0
原创粉丝点击