GCD

序言

这是最近整理出来的关于自己的一些想法

前提

首先要了解一些比较常用的英文术语:
dispatch 调度,派遣
retain 保持
in parallel 并行
in serial 串行,连续的
Concurrent 同时发生的
priority 优先级,优先权(pal o ri ti)
dispatch_suspend 调度暂停
dispatch_resume 调度恢复
dispatch_set_context 调度设置环(背/ 语)境,调度设置上下文
queue 队列,用于存放任务。一共有两种队列, 串行队列 和 并行队列。

什么是GCD

目前大多iOS程序员用的一种多线程开发技术,是一个block,写起来简单粗暴,执行方式分为同步和异步,我一般用异步,因为同步会阻塞当前线程并等待 Block 中的任务执行完才会让当前线程继续执行下去。
大致分为了三类:

  1. 全局的并行的queue
    eg: dispatch_queue_t a = dispatch_get_global_queue(优先级参数,0);

  2. 主线程的串行的queue,
    eg: dispatch_queue_t a = dispatch_get_main_queue();

  3. 自定义的queue ,
    eg: dispatch_queue_t a = dispatch_creat_queue("唯一标识”,串行还是并行参数);

关于调用

异步全局线程执行

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    });

第一个参数:
我们用priority指定队列的优先级,参数有

DISPATCH_QUEUE_PRIORITY_HIGH
DISPATCH_QUEUE_PRIORITY_DEFAULT
DISPATCH_QUEUE_PRIORITY_LOW

优先级由高到低,如果我们同时新建多个global_queue而又想按我们的顺序去执行,可以指定优先级,否则无法判定执行顺序

第二个参数:
作为保留字段备用(一般为0)。

异步主线程执行

dispatch_async(dispatch_get_main_queue(), ^{
});

需要注意的是主线程是一个特殊的串行队列,我们的UI刷新都要在这里操作,耗时的任务不能放在这里,否则会引发阻塞。

异步自建线程执行

 dispatch_async(dispatch_queue_create("aaa", DISPATCH_QUEUE_SERIAL), ^{
    });

第一个参数:aaa是这个线程的唯一标识,可以自行命名

第二个参数:标示改线程是串行还是并行执行,DISPATCH_QUEUE_SERIAL标示串行,并行用DISPATCH_QUEUE_CONCURRENT

关于串行和并行的区别

我们试着执行一个自建的串行队列,然后逐步执行任务1,2,3
每个任务执行完等待3秒

dispatch_queue_t myQueue = dispatch_queue_create("123", DISPATCH_QUEUE_SERIAL);

dispatch_async(myQueue, ^{
    NSLog(@"start task 1");
    [NSThread sleepForTimeInterval:3];
    NSLog(@"end task 1");
});

dispatch_async(myQueue, ^{
    NSLog(@"start task 2");
    [NSThread sleepForTimeInterval:3];
    NSLog(@"end task 2");
});

dispatch_async(myQueue, ^{
    NSLog(@"start task 3");
    [NSThread sleepForTimeInterval:3];
    NSLog(@"end task 3");
});

执行结果
在这里插入图片描述
这个执行说明任务是一个上一个结束才会执行下一个,如果参数改成DISPATCH_QUEUE_CONCURRENT,就会并发执行,无法判定先后,执行结果如下
在这里插入图片描述

关于group的概念

GCD另一个比较常用的方法就是dispatch_group_queue,可以理解为把相关的任务归并到一个组内来执行,通过监听组内所有任务的执行情况来做相应处理

创建方法
dispatch_group_t group = dispatch_group_create();
异步执行group
    dispatch_group_async(dispatch_group_create(), dispatch_queue_create("abc", DISPATCH_QUEUE_SERIAL), ^{
        ;
    });

第一个参数:对应的 group,之后可以通过dispatch_group_wait或者dispatch_group_notify监听group内任务的执行情况

第二个参数:block任务执行的线程队列,group内不同任务的队列可以不同

第三个参数:执行任务的block

关于group对应的一些用法

参考文献:https://www.jianshu.com/p/6faea7ef35bc

dispatch_group_enter

用于添加对应任务组中的未执行完毕的任务数,执行一次,未执行完毕的任务数加1,当未执行完毕任务数为0的时候,才会使dispatch_group_wait解除阻塞和dispatch_group_notify的block执行

void dispatch_group_enter(dispatch_group_t group);
dispatch_group_leave

用于减少任务组中的未执行完毕的任务数,执行一次,未执行完毕的任务数减1,dispatch_group_enterdispatch_group_leave要匹配,不然系统会认为group任务没有执行完毕

void dispatch_group_leave(dispatch_group_t group);
dispatch_group_wait

等待组任务完成,会阻塞当前线程,当任务组执行完毕时,才会解除阻塞当前线程

long dispatch_group_wait(dispatch_group_t group, 
                         dispatch_time_t timeout);

group ——需要等待的任务组
timeout ——等待的超时时间(即等多久),单位为dispatch_time_t。如果设置为DISPATCH_TIME_FOREVER,则会一直等待(阻塞当前线程),直到任务组执行完毕

dispatch_group_notify

待任务组执行完毕时调用,不会阻塞当前线程

void dispatch_group_notify(dispatch_group_t group,
                           dispatch_queue_t queue, 
                           dispatch_block_t block);

group ——需要监听的任务组
queue ——block任务执行的线程队列,和之前group执行的线程队列无关
block ——任务组执行完毕时需要执行的任务block

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值