GCD (Grand Central Dispatch)------多线程编程

时间:2021-10-26 05:16:15


转自: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]];

    });