GCD系列是阅读官方文件和在实践中总结的一些常见的GCD用法,基本涉及全部的GCD内容形成的集合文章,文章重点在与精简和全面覆盖。
学习本集合你可以了解:
1. GCD是如何做到多线程调度的
2. 对比其他iOS的多线程方案,GCD的优势和劣势
3. 如何使用GCD相关的API我将在后续不断补充详细内容和实际案例, 欢迎关注,提问和讨论
03-dispatch_after/dispatch_time-延迟调度和操作
04-dispatch_barrier_sync/async-线程阻塞
dispatch_queue
help both the system and your application to run faster, more efficiently, and with improved responsiveness.
Grand Central Dispatch (GCD) comprises language features, runtime libraries, and system enhancements that provide systemic, comprehensive improvements to the support for concurrent code execution on multicore hardware
GCD, operating at the system level, can better accommodate the needs of all running applications, matching them to the available system resources in a balanced fashion.
GCD provides and manages FIFO queues to which your application can submit tasks in the form of block objects. Work submitted to dispatch queues are executed on a pool of threads fully managed by the system. No guarantee is made as to the thread on which a task executes.
dispatch是一个简单强大的表达并发的抽象模型
- 在dispatch的内部,dispatch提供一系列提交的block先进先出的队列。
- block被提交到一系列由系统管理的线程池中,系统不保证这个Block会在哪一个线程执行。
多个队列提交Block的时候,系统会自动创建新的线程来并发执行这些Block,当线程执行完毕时,会被系统自动释放。
dispatch会按照先进先出的顺序每次调用一个Block去执行
不同的队列Queue之间不受影响,也就是说不同队列之间是并发执行Block
dispatch queue(调度队列)相对于提交的Block块来说事轻量级的
- 系统管理了一个线程池来处理调度队列和执行提交到队列的Block
调度队列有自己的执行线程,并且队列之间的交互是高度异步的
调度队列是通过dispatch_retain()和dispatch_release()来执行引用计数的
- 提交的Blocks会对Queue做一次引用直到执行完毕,当Queue的所有引用都被释放的时候,队列就会被系统销毁
dispatch_queue的主要API
void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
void dispatch_async_f(dispatch_queue_t queue, void *_Nullable context, dispatch_function_t work);
void dispatch_sync(dispatch_queue_t queue, DISPATCH_NOESCAPE dispatch_block_t block);
void dispatch_sync_f(dispatch_queue_t queue, void *_Nullable context, dispatch_function_t work);
dispatch_queue_t dispatch_get_main_queue(void) {
return DISPATCH_GLOBAL_OBJECT(dispatch_queue_t, _dispatch_main_q);
}
#define DISPATCH_QUEUE_PRIORITY_HIGH 2
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
#define DISPATCH_QUEUE_PRIORITY_LOW (-2)
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
typedef long dispatch_queue_priority_t;
dispatch_queue_t dispatch_get_global_queue(long identifier, unsigned long flags);
void dispatch_after(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block);
void dispatch_after_f(dispatch_time_t when, dispatch_queue_t queue, void *_Nullable context, dispatch_function_t work);
void dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
void dispatch_barrier_async_f(dispatch_queue_t queue, void *_Nullable context, dispatch_function_t work);
void dispatch_barrier_sync(dispatch_queue_t queue, DISPATCH_NOESCAPE dispatch_block_t block);
void dispatch_barrier_sync_f(dispatch_queue_t queue, void *_Nullable context, dispatch_function_t work);
void dispatch_apply(size_t iterations, dispatch_queue_t queue, DISPATCH_NOESCAPE void (^block)(size_t));
void dispatch_apply_f(size_t iterations, dispatch_queue_t queue, void *_Nullable context, void (*work)(void *_Nullable, size_t));