GCD的常用功能

1. dispatch_after

等待特定时间,异步的添加执行block到特定queue中

void dispatch_after(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block);
//when: 时间,dispatch_time_t或者dispatch_walltime
//queue: 执行的queue 被系统retain直到block完成
//block: 函数内部帮助调用者适时执行Block_copy and Block_release

dispatch_after_f

void dispatch_after_f(dispatch_time_t when, dispatch_queue_t queue, void *context, dispatch_function_t work);

2. dispatch_apply

同步的在指定的queue中执行指定次数 的block,可用来进行更有性能的迭代
此方法将block提交到指定的queue中执行 并且等所有迭代完成后才会返回;
如果目标队列是dispatch_get_global_queue迭代并发执行,因此应该保证block是可重入安全的,可以作为有效的并行for循环

void dispatch_apply(size_t iterations, dispatch_queue_t queue, void (^block)(size_t));
//iterations: 执行几次
//block: 执行事件 参数为当前执行次数

dispatch_apply 和 dispatch_apply_f 是同步函数,会阻塞当前线程直到所有循环迭代执行完成。

dispatch_apply_f

将函数多次执行

void dispatch_apply_f(size_t iterations, dispatch_queue_t queue, void *context, void (*work)(void *, size_t));

3.dispatch_once

在应用程序的生命周期内 只执行一次block内容
常用来初始化程序的单例数据
当多线程执行时,其内部会保证同步执行等待block完成

void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);
//predicate: dispatch_once_t指针 用来标记block是否已经被执行
//

dispatch_once_t

必须保证为全局或者静态变量,如果该值动态或者自动存储将会发生无法预知事件

dispatch_once_f

void dispatch_once_f(dispatch_once_t *predicate, void *context, dispatch_function_t function);

4.dispatch_barrier

当执行到barrier block 其并不会立即执行,而是等待当前正在执行的所有block完成后才会执行,而所有在barrier block后的block会等待barrier block执行完成后才执行

注意:
使用的queue应该为concurrent队列,并且使用dispatch_queue_create函数创建的

dispatch_barrier_async

提交一个异步执行的barrier block并立即返回

void dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
//queue: barrier block执行的队列,系统持有该队列直到block执行完成
//block:barrier block,这个block会被copy 和 retain直到执行完成

dispatch_barrier_async_f

void dispatch_barrier_async_f(dispatch_queue_t queue, void *context, dispatch_function_t work);

dispatch_barrier_sync

同步提交一个barrier block并等待block执行完成,会阻塞当前线程

void dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t block);
//queue: barrier block执行的队列
//block:barrier block,

dispatch_barrier_async不同,因为是函数是同步执行的,因此queue不会被retain,block也不会进行copy

dispatch_barrier_sync_f

void dispatch_barrier_sync_f(dispatch_queue_t queue, void *context, dispatch_function_t work);

5. dispatch_group_t

  1. group中的queue可以执行在不同queue,group中的blocks互相独立

  2. dispatch_group一直追踪group内的未完成的block的数量,并且GCD会retain该group直到与其关联的所有block完成

group 主要做的事情就是计算内部未完成blocks的数量
加到group中的block即会立即执行

dispatch_group_create

dispatch_group_t dispatch_group_create(void);
  1. group对象会维持内部未完成block的数量,dispatch_group_notify and dispatch_group_wait使用这个count来决定何时group完成

dispatch_group_async

将一个block提交到queue中执行,并与group关联

void dispatch_group_async(dispatch_group_t group, dispatch_queue_t queue, dispatch_block_t block);
//group: 与block关联的group 被系统持有直到block完成
// queue: block异步执行的队列,被系统持有直到block完成
// block: 异步执行,该函数会帮助调用者对block执行Block_copy and Block_release操作

group可以用来等待block执行完成

dispatch_group_async_f

void dispatch_group_async_f(dispatch_group_t group, dispatch_queue_t queue, void *context, dispatch_function_t work);

dispatch_group_enter && dispatch_group_leave

//明确指示有一个block进入group,将group内未完成的blocks计数加一
void dispatch_group_enter(dispatch_group_t group);
//明确指示有一个block已经完成,group未完成计数减1
void dispatch_group_leave(dispatch_group_t group);

可以使用这个函数 将一个block同时与多个group关联

dispatch_group_wait

同步的阻塞当前线程等待group中所有block完成,直到全部完成或者timeout

long dispatch_group_wait(dispatch_group_t group, dispatch_time_t timeout);
//返回值: 0表示成功执行所有block,非0表示超时
  1. 当group为空时,立即返回

一个group虽然可以wait多次,但是只wait从监测那一刻之前,group中的block完成状态,而在等待过程添加的block本次并不会监测

dispatch_group_wait

异步等待group中的task执行完成,调用block在指定queue中执行

void dispatch_group_notify(dispatch_group_t group, dispatch_queue_t queue, dispatch_block_t block);
//group: 等待的group,系统retaingroup直到block运行完成
//queue: group完成,block执行的queue,系统持有该queue直到block运行完成
//block: group完成后放入queue中执行的block,函数会帮助调用Block_copy and Block_release

当group为空时,立即返回
当notify block运行完成后,group为空

dispatch_time_t

typedef uint64_t dispatch_time_t

常用的time常量

//立即发生时间
DISPATCH_TIME_NOW
//无限远的时间
DISPATCH_TIME_FOREVER

dispatch_time

创建一个时间

dispatch_time_t dispatch_time(dispatch_time_t when, int64_t delta);

//int64_t delta: 纳秒数

dispatch_time的默认时钟是基于mach_absolute_time.

dispatch_walltime

根据wall clock创建一个绝对的时间

dispatch_time_t dispatch_walltime(const struct timespec *when, int64_t delta);
//when:结构体,创建的是绝对时间;传NULL表示当前时间

wall clock基于gettimeofday(_:_:)

dispatch_time区别:dispatch_time会在设备休眠(关机)时停止运行,dispatch_walltime会继续运行;即dispatch_time是设备运行的一段时间后某个时间点,而dispatch_walltime是绝对时间,与设备运行状态无关