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
group中的queue可以执行在不同queue,group中的blocks互相独立
dispatch_group
一直追踪group内的未完成的block的数量,并且GCD会retain该group直到与其关联的所有block完成
group 主要做的事情就是计算内部未完成blocks的数量
加到group中的block即会立即执行
dispatch_group_create
dispatch_group_t dispatch_group_create(void);
- group对象会维持内部未完成block的数量,
dispatch_group_notify
anddispatch_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表示超时
- 当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
是绝对时间,与设备运行状态无关