转自:http://www.cnblogs.com/taintain1984/p/3709146.html
参考:http://blog.csdn.net/q199109106q/article/details/8566300
三个函数:
void dispatch_async(dispatch_queue_t queue,dispatch_block_t block);
dispatch_queue_t dispatch_get_global_queue(long priority, unsigned long flags);
dispatch_get_main_queue();
dispatch_async 函数会将传入的block块放入指定的queue里运行。这个函数是异步的,这就意味着它会立即返回而不管block是否运行结束。因此,我们可以在block里运行各种耗时的操作(如网络请求) 而同时不会阻塞UI线程。
dispatch_get_global_queue 会获取一个全局队列,我们姑且理解为系统为我们开启的一些全局线程。我们用priority指定队列的优先级,而flag作为保留字段备用(一般为0)。
dispatch_get_main_queue 会返回主队列,也就是UI队列。它一般用于在其它队列中异步完成了一些工作后,需要在UI队列中更新界面(比如上面代码中的[self updateUIWithResult:result])的情况。
为了良好的用户体验,读取数据的操作会倾向于在后台运行,这样以避免阻塞主线程,然后在主线程更新UI
GCD里就有三种queue来处理.
1. Main queue:------运行在主线程,由dispatch_get_main_queue获得
2.Serial quque(private dispatch queue,其中dispatch_queue_t就是一种)
serial queues(串行队列)又称私有调度队列(private),每次运行一个任务,可以添加多个,执行次序FIFO.一般用再对特定资源的同步访问上,每一个串行队列之间是并发的。
3. Concurrent queue(global dispatch queue,其中dispatch_time_t就是一种):
并行队列,又称global dispatch queue。并行队列虽然可以并发的执行多个任务,但是任务开始执行的顺序和其加入队列的顺序相同。我们自己不能去创建并行调度队列。
// 后台执行: dispatch_async(dispatch_get_global_queue(0, 0), ^{ // something }); // 主线程执行: dispatch_async(dispatch_get_main_queue(), ^{ // something }); // 一次性执行:&表示取地址符,这个是定义一个静态变量,然后在dispatch_once函数第一次运行时写入数据,之后就不会再次写入,可以保证后面block函数内部的代码只被执行一次 static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ // code to be executed once });
// 延迟2秒执行: double delayInSeconds = 2.0; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ // code to be executed on the main queue after delay }); // 自定义dispatch_queue_t dispatch_queue_t urls_queue = dispatch_queue_create("blog.devtang.com", NULL); dispatch_async(urls_queue, ^{ // your code }); dispatch_release(urls_queue); // 合并汇总结果 dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{ // 并行执行的线程一 }); dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{ // 并行执行的线程二 }); dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{ // 汇总结果 });
Demo:
// dispatch_get_global_queue 并行队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//创建一个并行队列
dispatch_async(queue, ^{
int i = 0;
while (i < 1000000000 && cancel == NO) {
i++;
}
NSLog(@"Task end: i = %d", i);
//这个不会执行,因为在之前,gcd task已经结束
[tempView removeFromSuperview];
});
//1s 之后执行这个方法
double delayInSeconds = 1.0;
// 定义调度队列延后执行时间
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
NSLog(@"A GCD Task Start");
cancel = YES;
[tempView setBackgroundColor:[UIColor blackColor]];
});