1. 基本概念
- 同步:执行完再返回
- 异步:直接返回
- 并行:queue中的任务可同时进行
- 串行:queue 中的任务按顺利进行(fifo)
2. 常用的几种queue
a. main queue ,主线程,有关ui的操作必须在这个queue中进行
dispatch_get_main_queue()
b. global queue, 系统提供的并行queue
dispatch_get_global_queue ( long identifier, unsigned long flags )
c . 自己创建queue(一般自己创建的都是串行的,因为并行的直接用global queue即可)
dispatch_queue_t dispatch_queue_create ( const char *label, dispatch_queue_attr_t attr );
3. 几种常见的queue task
dispatch_async :异步执行
dispatch_syn :同步执行
dispatch_after(dispatch_time_t when,dispatch_queue_t queue, block)
在将来的某个时刻(when),异步执行 block;
when 可用dispatch_time ( dispatch_time_t when, int64_t delta )函数获取,这里如果when 设置为DISPATCH_TIME_NOW,则为目前的时间+delta
dispatch_apply(size_t iteration,dispatch_queue_t queue, void(^block)(size_t))
多次同步执行block,全部执行完之后,函数才返回,
如果queue为global queue,则并行调用block
dispatch_once(dispatch_once_t *predicate, block)
app生命周期内,仅执行一次block,在创建单例的时候很有用
dispatch_semaphore_t dispatch_semaphore_create(long value)
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
dispatch_semaphore_signal(dispatch_semaphore_t dsema);
以上三个函数配合使用,可方便管理资源的使用.
dispatch_semaphore_create(long value )创建一个semaphor, value代表信号量,将value设为0可方便两个线程(queue)协调完成某个事件,将value设为大于0,方便关于一个有限资源池;
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout),将信号量-1(或者说占用资源),此时如果信号量 <0, 这个函数将堵塞当前线程,直到信号量>=0;
dispatch_semaphore_signal(dispatch_semaphore_t dsema), 将信号量+1(或者说是放占用资源),此时之前信号量< 0,则唤醒等待的线程
比如当前queue为queue 1, 此时需要异步处理任务A,那么新开一个queue(2),把任务A dispatch 到queue 2后,queue 1 开始处理任务B, 但是任务B完成一半后,发现需要任务A完成,才能继续,此时用以上机制就非常方便
dispatch_group_create();
dispatch_group_enter(group);标明一个block进入了group
dispatch_group_leave(group);表明一个block完成,离开了group
dispatch_group_notify(group,queue,block);当进入group 的所有block都已经完成,则在queue中调用block
用以上函数可对blocks进行同步
(用 dispatch_barrier_async(queue,block)也可以达到这样的效果)
4. 用GCD 创建timer
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, <#dispatchQueue#>); dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, <#intervalInSeconds#> * NSEC_PER_SEC, <#leewayInSeconds#> * NSEC_PER_SEC); dispatch_source_set_event_handler(timer, ^{ <#code to be executed when timer fires#> }); dispatch_resume(timer); // INVALIDATE dispatch_source_cancel(<#dispatch_source_t source#>)
5.如何取消queue中的任务
GCD 很难取消queue中的任务,基本把任务加入queue之后,用户就不能掌控了,
如果需要取消queue中的任务,使用NSOperationQueue ,这个类中有方法取消operaiton