本文复制、参考自文章:iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用 ,主要为了加强个人对知识的理解和记忆,不做他用。原作者声明:

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

这里对原作者的辛勤工作表示感谢!

1. 简介

GCD (Grand Central Dispatch) 是建立任务并行执行的线程池模式的基础上的,以优化支持多核、多处理器系统。

GCD的工作原理是:让程序平行排队的特定任务,根据可用的处理资源,安排他们在任何可用的核心上执行任务。一个任务可以是一个函数(function)或者是一个block。

GCD的底层依然是用线程实现,不过不必关心实现细节。

GCD的FIFO队列称为 调度队列(dispatch queue), 它可以保证先来的先执行。dispatch 的、queue 分为以下3种:

(1) Serial (连续调度队列)

又称为 私有调度队列(pirvate dispatch queue), 同时只执行一个任务。Serial queue通常用于同步访问特定的资源或数据。当创建多个Serial queue时,虽然它们各自队列内是单独执行的,但队列间是并发执行的。

(2) Concurrent (并发调度队列)

又称为 全局调度队列(global dispatch queue), 可以并发地执行队列中的多个任务,但是执行完成的顺序是随机的。

(3) Main dispatch queue(主调度队列)

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

2. 调度队列的使用

2.1 常用的方法 dispatch_async

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

用GCD实现这个流程比前面介绍的NSThread\NSOperation的方法都要简单,代码如下:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
// 耗时的操作 dispatch_async(dispatch_get_main_queue(), ^{
// 更新界面
});
});

针对之前图片加载的示例:

- (void)viewDidLoad
{
[super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib.
// NSThread* thread = [[NSThread alloc] initWithTarget:self selector:@selector(downloadImage:) object:kURL];
// [thread start]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
NSURL* url = [NSURL URLWithString:kURL];
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;
});
}
}); }

GCD会自动根据任务在多核处理器上分配资源,优化程序。

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

dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEU_PRIORITY_DEFAULT, );

系统还提供了一个主调度队列 main_queue

dispatch_queue_t mainQueue = dispatch_get_main_queue();

这些队列都是全局队列,,不用retain或release。

2.2 dispatch_group_async的使用

dispatch_group_async可以实现监听一组任务是否完成,完成后再通知执行其他的操作。如下示例:

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:];
NSLog(@"group1");
}); dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:];
NSLog(@"group2");
}); dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:];
NSLog(@"group3");
}); dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"updateUI");
});

前3个dispatch_group_async执行是异步的,顺序不定。

2.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:];
NSLog(@"dispatch_async1");
}); dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:];
NSLog(@"dispatch_async2");
}); dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:];
NSLog(@"dispatch_async3");
}); dispatch_barrier_async(queue, ^{
NSLog(@"dispatch_barrier_async");
[NSThread sleepForTimeInterval:];
}); dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:];
NSLog(@"dispatch_async4");
});

同样的,前3个dispatch_async执行是异步的,顺序不定。

2.4 dispatch_apply

执行某个代码片段N次。

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
dispatch_apply(, queue, ^(size_t index) {
NSLog(@"dispatch_apply: index: %d", index);
});

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

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

iOS 多线程学习笔记 —— GCD的更多相关文章

  1. iOS 多线程学习笔记 —— NSThread

    本文复制.参考自文章:iOS多线程编程之NSThread的使用  ,主要为了加强个人对知识的理解和记忆,不做他用.原作者声明: 著作权声明:本文由http://blog.csdn.net/totogo ...

  2. iOS 多线程学习笔记 —— NSOperation

    本文复制.参考自文章:iOS多线程编程之NSOperation和NSOperationQueue的使用 ,主要为了加强个人对知识的理解和记忆,不做他用.原作者声明: 著作权声明:本文由http://b ...

  3. iOS多线程知识总结--GCD

    iOS多线程知识总结--GCD 1. iOS中苹果提供4钟方案来帮助我们实现多线程: (1) 纯C语言的pthread,偏底层,需要程序员手动管理线程的生命周期,基本不用. (2) OC语言的NSTr ...

  4. java多线程学习笔记——详细

    一.线程类  1.新建状态(New):新创建了一个线程对象.        2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...

  5. iOS多线程开发之GCD(中篇)

    前文回顾: 上篇博客讲到GCD的实现是由队列和任务两部分组成,其中获取队列的方式有两种,第一种是通过GCD的API的dispatch_queue_create函数生成Dispatch Queue:第二 ...

  6. JAVA多线程学习笔记(1)

    JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...

  7. 多线程学习笔记九之ThreadLocal

    目录 多线程学习笔记九之ThreadLocal 简介 类结构 源码分析 ThreadLocalMap set(T value) get() remove() 为什么ThreadLocalMap的键是W ...

  8. java进阶-多线程学习笔记

    多线程学习笔记 1.什么是线程 操作系统中 打开一个程序就是一个进程 一个进程可以创建多个线程 现在系统中 系统调度的最小单元是线程 2.多线程有什么用? 发挥多核CPU的优势 如果使用多线程 将计算 ...

  9. Java多线程学习笔记(一)——多线程实现和安全问题

    1. 线程.进程.多线程: 进程是正在执行的程序,线程是进程中的代码执行,多线程就是在一个进程中有多个线程同时执行不同的任务,就像QQ,既可以开视频,又可以同时打字聊天. 2.线程的特点: 1.运行任 ...

随机推荐

  1. Mono For Android的项目发布

    Mono for Android的发布步骤: 1.选择项目名称鼠标右键,选择Options选项. 2.弹出工程选项框,选择Android Build,勾选 Supported ABIS里面的所有项. ...

  2. 再次回首 TCP Socket服务器编程

    转载:http://www.cnblogs.com/zc22/archive/2010/06/27/1766007.html ------------------ 前言 --------------- ...

  3. 第一节 WCF概述

    主要内容: 1.什么是WCF? 2.WCF的背景介绍. 引例:(WCF用来解决什么事情) 一家汽车租赁公司决定创建一个新的应用程序,用于汽车预定 • 该租车预定应用程序的创建者知道,应用程序所实现的业 ...

  4. 基于url拦截实现权限控制

    用户表,角色表,用户角色表,权限表,权限角色表 1.用户通过认证(可以是验证用户名,密码等) 2.登陆拦截器,为公开的url放行, 登陆时,将用户信息放入session中,获得用户的权限集合,将集合放 ...

  5. Angularjs总结(三)摸态框的使用

    静态页面: <input class="btn btnStyle " value="提 取" type="button" ng-cli ...

  6. Html table 实现Excel多格粘贴

    Html table 实现Excel多格粘贴 电商网站的后台总少不了各种繁杂数据的录入,旁边的运营妹子录完第138条商品的时候,终于忍不住转身吼到:为什么后台的录入表不能像Excel那样多行粘贴!!! ...

  7. UVA 10817 Headmaster's Headache(DP +状态压缩)

    Headmaster's Headache he headmaster of Spring Field School is considering employing some new teacher ...

  8. 配置并学习微信JS-SDK(2)—图片接口

    测试地址:http://www.qq210.com/shoutu/android 检查图像接口 选择本地或拍照的图片 上传选择的图片 预览上传的图片 //1.检查图像接口 document.query ...

  9. 对于volatile的理解

    哎.要学的东西太多,时间太少.一周的工作下来要总结的东西太多,还处理不完,越积越多.大周末的好想出去玩啊.... 得嘞,废话止于此. 无聊时候乱看网页发现了volatile的一篇文章,以前曾经对vol ...

  10. 基于TCP的NAT子网穿透实验

    不得不说,在国内IP紧缺的现状下,NAT发挥了无比巨大的作用:它以把IP和端口重新分配的方式,满足了广大人民群众上网的强烈需求.但是对于个人服务器以及在内网中基于网络的嵌入式设备,却是个比较尴尬的事情 ...