总结下 GCD.
Basics
CGD 是对线程的抽象。将线程管理交给系统实现,程序员只需要将想执行的任务加入到相应的队列中。
只有global queue 会被调度运行。当创建自己的queue 的时候,实际上会被set target 到global queue 去,custome queue 将要执行的 block 交给 global queue 执行。(存疑,只在一本书上看到这样的描述)
Concurrent Disptach Queue 会由系统来决定应当生成的线程数。而 Serial Dispatch Queue 每创建一条都会创建一条新线程。(大量生成 Serial Queue 会消耗大量内存)
iOS 6.0 之后 GCD 已经加入 ARC, 无需手动释放。
Set target
|
|
queueA 将 block 传给 queueB 执行
Suspend & Resume
|
|
queue 被 suspend 之后将停止执行队列中的block. (当前block会继续执行到结束)
dispatch_barrier_async
|
|
dispatch_barrier_async 加入block 之前的 blocks 执行完毕后, 执行 barrier 加入的 block, 完成之后再执行之后加入的 block
case: read block 用普通的 dispatch_async, write block 用 dispatch_barrier_async。比如一个array,可以用这样的方法来保证其线程安全。
dispatch group
将几个block group 起来,全部执行完后通知用户
dispatch_group_wait 设置等待时间,到时间直接返回,若为0 则全部完成。设置 DISPATCH_TIME_FOREVER 永远等待,DISPTACH_TIME_NOW 立即返回。
dispatch_apply
dispatch_sync 的复数版本
dispatch semaphore
计数信号
dispatch_once
略
dispatch source
dispatch source data add
|
|
注意不可发送0 或者 复数
dispatch timer
|
|
start - start after the start interval
interval - execution interval. the handler will be called with after the first execution repeately with the interval. set to DISPATCH_TIME_FOREVER if you want to perform it only once. (use dispatch_after if you want to perform some task after a delay only once)
leeway - the time allowed for delay. used a hint to the system
Queue sepcific data
Similiar to the Associated Object. Assign a key-value pair to a queue. A release function is required.
如果找不到key, 会向target queue 查询。
例子
因为dispatch_get_current_queue 可能会造成死锁,如下,get current queue 检查为当前queue 为queue B, 所以调用 dispatch_sync(queueA, …), 造成死锁(因为最外面还套一个 dispatch_sync(queueA, …))
上面的dispatch_sync_safe 重入,导致deadlock
解决方法:
上面利用Queue sepcific data 会像target queue询问的特性来避免死锁。
不过只能应对这种只有两条queue 的情况,而且只能给最外面的queue 加上标签。(所以有啥用啊。。。)
References
- iOS 7 Programming: Pushing the limit
- Objective-C 高级编程