GCD

两个特殊队列:

dispatch_get_main_queue()主队列,串行队列。
dispatch_get_global_queue(0, 0)全局并发队列。这个队列是系统维护的,会被用来处理很多系统级事件。

最简单的block:

dispatch_block_t这是个无参无返回值的block。

关于同步异步函数:

dispatch_sync同步函数没有开启线程的能力。所有的代码都会在当前线程立即执行。
dispatch_async异步函数有开启线程的能力。

关于串行并行队列:

dispatch_queue_create(0,0)
DISPATCH_CURRENT_QUEUE_LABEL串行队列遵循FIFO原则,先进先出。
DISPATCH_QUEUE_CONCURRENT并行队列,之间不会相互影响会各自执行。执行顺序与加入队列顺序有关。
排列组合之后,就有了这么一套机制,如下图:

image.png

知识点较多的主要是同步函数串行队列。产生堵塞的原因本质上还是任务执行顺序的问题。如下经典代码就会产生堵塞(死锁):

 // 同步队列
    dispatch_queue_t queue = dispatch_queue_create("xxx", DISPATCH_QUEUE_SERIAL);
    NSLog(@"1");
    // 异步函数
    dispatch_async(queue, ^{
        NSLog(@"2");
        // 同步
        dispatch_sync(queue, ^{
             NSLog(@"3");
        });
          NSLog(@"4");
    });
    NSLog(@"5");

分析图如下


image.png

本质上,异步函数里的代码是加入队列后,按顺序执行的。所以会执行2->同步->4
但是,同步函数的性质又会让代码立即执行。所以在执行同步函数的时候,会要求立即执行log3
但是log3这个任务因为串行队列顺序的原因,必须等到log4执行完毕之后才会执行。
此时发生了log4log3相互等待的情况,而产生了堵塞。

这只是同步串行会出现问题的一种方式。单纯的在主线程中使用同步串行,是没有问题,而且借助其一定会按顺序执行的特性。还能达到某些锁的功能:如经典的购票问题:

- (void)saleTickes {
    self.tickets = 20;
    _queue = dispatch_queue_create("xxx", DISPATCH_QUEUE_SERIAL);
    while (self.tickets > 0) {
        // 使用串行队列,同步任务卖票
        dispatch_sync(_queue, ^{
            // 检查票数
            if (self.tickets > 0) {
                self.tickets--;
            }
        });
    }
}

代码很简单,不需要解释。这个demo只是说明同步串行的效果。其实这段代码意义不大,因为实现购票必定要在异步并发队列里才会更好的达到效果。如下:

- (void)saleTickes {
    NSLock *lock = [NSLock new];
    _tickets = 20;
    _queue = dispatch_queue_create("Cooci", DISPATCH_QUEUE_CONCURRENT);
    while (self.tickets > 0) {
        [lock lock];
        dispatch_async(_queue, ^{
            // 检查票数
            if (self.tickets > 0) {
                self.tickets--;
                NSLog(@"还剩 %zd %@", self.tickets, [NSThread currentThread]);
            } else {
                NSLog(@"没有票了");
            }
            [lock unlock];
        });
    }
}

栅栏函数:

栅栏函数的用法,多用于控制并发队列的执行时机,并且只用于控制唯一一个并发队列(控制串行队列没有意义)。其中的barrier单词很好的说明了他的作用。就是个挡路的:在我之前的任务都要被我挡住,等我执行完毕之后,之后的任务才会执行
dispatch_barrier_sync同步栅栏函数:不仅仅会阻挡 并发队列的任务,还会阻挡 当前线程的任务 。直至该函数 之前的并发队列任务 执行完毕后,才会继续执行 当前线程的任务后面的并发任务
dispatch_barrier_async异步栅栏函数:只阻挡 并发队列的任务 。不会阻挡 当前线程的任务 。所以 当前线程的任务 ,都会比 所有的并发队列的任务 先执行。
demo如下:就不解释了

- (void)demo2{
    dispatch_queue_t concurrentQueue = dispatch_queue_create("cooci", DISPATCH_QUEUE_CONCURRENT);
    /* 1.异步函数 */
    dispatch_async(concurrentQueue, ^{
        for (NSUInteger i = 0; i < 5; i++) {
            NSLog(@"download1-%zd-%@",i,[NSThread currentThread]);
        }
    });
    
    dispatch_async(concurrentQueue, ^{
        for (NSUInteger i = 0; i < 5; i++) {
            NSLog(@"download2-%zd-%@",i,[NSThread currentThread]);
        }
    });
    
    /* 2. 栅栏函数 */
    dispatch_barrier_sync(concurrentQueue, ^{
        NSLog(@"---------------------%@------------------------",[NSThread currentThread]);
    });
    NSLog(@"加载那么多,喘口气!!!");
    /* 3. 异步函数 */
    dispatch_async(concurrentQueue, ^{
        for (NSUInteger i = 0; i < 5; i++) {
            NSLog(@"日常处理3-%zd-%@",i,[NSThread currentThread]);
        }
    });
    NSLog(@"**********起来干!!");
    
    dispatch_async(concurrentQueue, ^{
        for (NSUInteger i = 0; i < 5; i++) {
            NSLog(@"日常处理4-%zd-%@",i,[NSThread currentThread]);
        }
    });
}

调度组:

用这个也可以控制任务调度顺序。用法如下:

 - (void)groupDemo {
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        NSLog(@"第一个走完了");
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        NSLog(@"第二个走完了");
        dispatch_group_leave(group);
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"所有任务完成,可以更新UI");
        
    });
}

注意:
1.dispatch_group_enterdispatch_group_leave需要成对出现。
2.dispatch_group_enter 多于 dispatch_group_leave 不会调用通知
3.dispatch_group_enter 少于 dispatch_group_leave 会奔溃
4.所有的dispatch_group_enter都要在dispatch_group_notify之前执行。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容