本文复制、参考自文章: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. 日志记录组件[Log4net]详细介绍

    转载:http://www.cnblogs.com/liwei6797/archive/2007/04/27/729679.html 因为工作中有要用到Log记录,找到一篇不错的文章,就转了过来. 一 ...

  2. Mvc网站开发知识

    网站开发基本本步骤 mvc是一个设计模式 网站开发前台页面技术 页面设计:Html css+Div 页面特效:JavaScript,jQuery oop编程核心公共技能 c#基础语法与程序逻辑 面向对 ...

  3. sqlserver2005唯一性约束

    [转载]http://blog.163.com/rihui_7/blog/static/21228514320136193392749/ 1.设置字段为主键就是一种唯一性约束的方法,如   int p ...

  4. 深入理解shared pool共享池之library cache系列一

    结论 1,oradebug dump library_cache不同级别dump的library cache内容及粒度会有所区别,具体见测试开始部分2,本文测示基于oradebug dump libr ...

  5. 【转】NHibernate入门教程

    开源框架完美组合之Spring.NET + NHibernate + ASP.NET MVC + jQuery + easyUI 中英文双语言小型企业网站Demo 摘要: 热衷于开源框架探索的我发现A ...

  6. 将CString(unicode)转换为char*(ANSI)

    1.将CString(unicode)转换为char*(ANSI) CString strServIP; pChat->GetDlgItemText(IDC_IP,strServIP); ] = ...

  7. Bad owner or permissions on .ssh/config

    Bad owner or permissions on $HOME/.ssh/config The ssh with RHEL 4 is a lot more anal about security ...

  8. 安装ImageMagick扩展出现configure: error: not found. Please provide a path to MagickWand-config or Wand- config program

    安装ImageMagick扩展报错: checking ImageMagick MagickWand API configuration program... checking Testing /u ...

  9. 如何设置路由器实现静态IP配置

    一.概述 嵌入式开发者,经常面对这样的环境:PC(windows)+虚拟机(linux)+开发板.我们希望三者都能相互通信,而且可以联网. 对于实验室只提供一根网线,而自己没有额外的增加端口数量的设备 ...

  10. 前端开发福音!阿里Weex跨平台移动开发工具开源-b

    阿里巴巴今天在Qcon大会上宣布跨平台移动开发工具Weex开放内测邀请.Weex能够完美兼顾性能与动态性,让移动开发者通过简捷的前端语法写出Native级别的性能体验,并支持iOS.安卓.YunOS及 ...