iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用

145397人阅读 评论(40) 收藏 举报
分类:

介绍:

Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其他的对称多处理系统的系统。这建立在任务并行执行的线程池模式的基础上的。它首次发布在Mac OS X 10.6 ,iOS 4及以上也可用。

设计:

GCD的工作原理是:让程序平行排队的特定任务,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务。

一个任务可以是一个函数(function)或者是一个block。 GCD的底层依然是用线程实现,不过这样可以让程序员不用关注实现的细节。

GCD中的FIFO队列称为dispatch queue,它可以保证先进来的任务先得到执行
dispatch queue分为下面三种:

Serial      

又称为private dispatch queues,同时只执行一个任务。Serial queue通常用于同步访问特定的资源或数据。当你创建多个Serial queue时,虽然它们各自是同步执行的,但Serial queue与Serial queue之间是并发执行的。

Concurrent

又称为global dispatch queue,可以并发地执行多个任务,但是执行完成的顺序是随机的。

Main dispatch queue

它是全局可用的serial queue,它是在应用程序主线程上执行任务的。

我们看看dispatch queue如何使用

1、常用的方法dispatch_async

为了避免界面在处理耗时的操作时卡死,比如读取网络数据,IO,数据库读写等,我们会在另外一个线程中处理这些操作,然后通知主线程更新界面。

用GCD实现这个流程的操作比前面介绍的NSThread  NSOperation的方法都要简单。代码框架结构如下:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // 耗时的操作
    dispatch_async(dispatch_get_main_queue(), ^{
        // 更新界面
    });
});
如果这样还不清晰的话,那我们还是用上两篇博客中的下载图片为例子,代码如下:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSURL * url = [NSURL URLWithString:@"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"];
        NSData * data = [[NSData alloc]initWithContentsOfURL:url];
        UIImage *image = [[UIImage alloc]initWithData:data];
        if (data != nil) {
            dispatch_async(dispatch_get_main_queue(), ^{
                self.imageView.image = image;
             });
        }
    });

运行显示:


是不是代码比NSThread  NSOperation简洁很多,而且GCD会自动根据任务在多核处理器上分配资源,优化程序。

系统给每一个应用程序提供了三个concurrent dispatch queues。这三个并发调度队列是全局的,它们只有优先级的不同。因为是全局的,我们不需要去创建。我们只需要通过使用函数dispath_get_global_queue去得到队列,如下:

dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  

这里也用到了系统默认就有一个串行队列main_queue

dispatch_queue_t mainQ = dispatch_get_main_queue();  

虽然dispatch queue是引用计数的对象,但是以上两个都是全局的队列,不用retain或release。

2、dispatch_group_async的使用

dispatch_group_async可以实现监听一组任务是否完成,完成后得到通知执行其他的操作。这个方法很有用,比如你执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了。下面是一段例子代码:

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"group1");
    });
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"group2");
    });
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:3];
        NSLog(@"group3");
    });
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"updateUi");
    });
    dispatch_release(group);
dispatch_group_async是异步的方法,运行后可以看到打印结果:

2012-09-25 16:04:16.737 gcdTest[43328:11303] group1
2012-09-25 16:04:17.738 gcdTest[43328:12a1b] group2
2012-09-25 16:04:18.738 gcdTest[43328:13003] group3
2012-09-25 16:04:18.739 gcdTest[43328:f803] updateUi

每个一秒打印一个,当第三个任务执行后,upadteUi被打印。


3、dispatch_barrier_async的使用

dispatch_barrier_async是在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行

例子代码如下:

    dispatch_queue_t queue = dispatch_queue_create("gcdtest.rongfzh.yc", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"dispatch_async1");
    });
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:4];
        NSLog(@"dispatch_async2");
    });
    dispatch_barrier_async(queue, ^{
        NSLog(@"dispatch_barrier_async");
        [NSThread sleepForTimeInterval:4];

    });
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"dispatch_async3");
    });

打印结果:

2012-09-25 16:20:33.967 gcdTest[45547:11203] dispatch_async1

2012-09-25 16:20:35.967 gcdTest[45547:11303] dispatch_async2

2012-09-25 16:20:35.967 gcdTest[45547:11303] dispatch_barrier_async

2012-09-25 16:20:40.970 gcdTest[45547:11303] dispatch_async3

请注意执行的时间,可以看到执行的顺序如上所述。

4、dispatch_apply 

执行某个代码片段N次。
dispatch_apply(5, globalQ, ^(size_t index) {
    // 执行5次
});

本篇使用的到的例子代码:http://download.csdn.net/detail/totogo2010/4596471

GCD还有很多其他用法,可以参考官方文档

参考的文档还有:http://en.wikipedia.org/wiki/Grand_Central_Dispatch

前两篇多线程博文:iOS多线程编程之NSThread的使用

    iOS多线程编程之NSOperation和NSOperationQueue的使用

著作权声明:本文由http://blog.csdn.net/totogo2010/原创,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!


查看评论

dispatch_async 与 dispatch_get_global_queue

#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) - (void)...
  • EricSuper
  • EricSuper
  • 2011-11-22 08:43:22
  • 47990

iOS开发之:dispatch_async 与 dispatch_get_global_queue 的使用方法

Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法。 dispatch queue分成以下三种: 1)运行在主线程的Main queue,通过dispat...
  • u013321328
  • u013321328
  • 2016-01-13 19:04:02
  • 8907

GCD 之三: Main Dispatch Queue/Global Dispatch Queue

第二种方法是获取系统标准提供的Dispatch Queue。        实际上不用特意生成Dispatch Queue系统也会给我们提供几个。那就是Main Dispatch Queue和Glo...
  • womendeaiwoming
  • womendeaiwoming
  • 2014-04-06 22:03:05
  • 1428

GCD之dispatch queue深入浅出

iOS中多线程编程工具主要有:  NSThreadNSOperationGCD 这三种方法都简单易用,各有千秋.但无疑GCD是最有诱惑力的,因为其本身是apple为多核的并行运算提出的解决方案.虽然...
  • samuelltk
  • samuelltk
  • 2013-07-24 16:39:14
  • 30237

iOS学习笔记42—利用dispatch_once创建单例

在之前有一篇学习笔记中,记载了一篇如何在OC中实现单例的文章:《IOS学习笔记4—Objective C—创建单例》自苹果引入了Grand Central Dispatch (GCD)(Mac O...
  • tangren03
  • tangren03
  • 2013-02-28 16:02:48
  • 36672

GCD入门介绍四---- dispatch_group_async和dispatch_barrier_async

我们在开发的过程中,可能碰到如下的情况: 1.异步下载两张图片,然后合并成一张图片。 2....
  • jasonjwl
  • jasonjwl
  • 2016-01-30 20:40:32
  • 1538

GCD 信号量控制并发(dispatch_semaphore)以及dispatch_group_async

1、dispatch_semaphore 当我们在处理一系列线程的时候,当数量达到一定量,在以前我们可能会选择使用NSOperationQueue来处理并发控制,但如何在GCD中快速的控制并发呢? ...
  • wlm0813
  • wlm0813
  • 2016-09-03 13:52:53
  • 1660

完整详解GCD系列(三)dispatch_group

完整详解GCD系列三,详细的阐述了dispatch_group的常用方法,通过实例解析如何使用。并且实例解析了dispatch_group_enter/dispatch_group_leave。提供了...
  • Hello_Hwc
  • Hello_Hwc
  • 2014-11-23 11:23:21
  • 7076

iOSGDC多线程使用

//同步执行的概念就是,我获取完第一张图片的数据,执行了for循环第一句返回了img后,我才能执行第二句,UI界面的刷新。for (int i = 0 ; i dispatch_sync(disp...
  • wenzfcsdn
  • wenzfcsdn
  • 2015-02-03 11:24:02
  • 1230

IOS GDC线程原理及代码实现

GCD,全称Grand Central Dispath,是苹果开发的一种支持并行操作的机制
  • lyh9222
  • lyh9222
  • 2015-01-15 23:24:40
  • 1219
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 573万+
    积分: 2万+
    排名: 372
    博客专栏
    我的其他站点
    最新评论