iOS 多线程学习笔记 —— GCD
本文复制、参考自文章: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的更多相关文章
- iOS 多线程学习笔记 —— NSThread
本文复制.参考自文章:iOS多线程编程之NSThread的使用 ,主要为了加强个人对知识的理解和记忆,不做他用.原作者声明: 著作权声明:本文由http://blog.csdn.net/totogo ...
- iOS 多线程学习笔记 —— NSOperation
本文复制.参考自文章:iOS多线程编程之NSOperation和NSOperationQueue的使用 ,主要为了加强个人对知识的理解和记忆,不做他用.原作者声明: 著作权声明:本文由http://b ...
- iOS多线程知识总结--GCD
iOS多线程知识总结--GCD 1. iOS中苹果提供4钟方案来帮助我们实现多线程: (1) 纯C语言的pthread,偏底层,需要程序员手动管理线程的生命周期,基本不用. (2) OC语言的NSTr ...
- java多线程学习笔记——详细
一.线程类 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...
- iOS多线程开发之GCD(中篇)
前文回顾: 上篇博客讲到GCD的实现是由队列和任务两部分组成,其中获取队列的方式有两种,第一种是通过GCD的API的dispatch_queue_create函数生成Dispatch Queue:第二 ...
- JAVA多线程学习笔记(1)
JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...
- 多线程学习笔记九之ThreadLocal
目录 多线程学习笔记九之ThreadLocal 简介 类结构 源码分析 ThreadLocalMap set(T value) get() remove() 为什么ThreadLocalMap的键是W ...
- java进阶-多线程学习笔记
多线程学习笔记 1.什么是线程 操作系统中 打开一个程序就是一个进程 一个进程可以创建多个线程 现在系统中 系统调度的最小单元是线程 2.多线程有什么用? 发挥多核CPU的优势 如果使用多线程 将计算 ...
- Java多线程学习笔记(一)——多线程实现和安全问题
1. 线程.进程.多线程: 进程是正在执行的程序,线程是进程中的代码执行,多线程就是在一个进程中有多个线程同时执行不同的任务,就像QQ,既可以开视频,又可以同时打字聊天. 2.线程的特点: 1.运行任 ...
随机推荐
- Java基础--Java内存管理与垃圾回收
Java自动内存管理 在讲解内存管理之前,首先需要了解对象和对象引用的区别 对象是类的一个实例,以人这个类为例,Person是我们定义的一个类 public class Person{} publ ...
- java加密类型和算法名称
项目里有各种加密方法,但从来没有仔细研究过.一般只是copy.这几天遇到一些问题,看了一下加密代码,觉得有些疑惑. 我们知道jdk已经为我们包装好了很多的算法.但究竟包装了哪些算法,怎么去掉这些算法我 ...
- HUST 4681 String (DP LCS变形)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4681 题目大意:给定三个字符串A,B,C 求最长的串D,要求(1)D是A的字序列 (2)D是B的子序列 ...
- Ubuntu 之旅 —— 解决sudo: source: command not found错误
$ sudo -s # source /etc/profile
- [转] js call
call 方法 转自: http://www.cnblogs.com/sweting/archive/2009/12/21/1629204.html调用一个对象的一个方法,以另一个对象替换当前对象. ...
- 【CSS sprites (CSS图片精灵) 详解】
本文包含 CSS sprites 简介.原理.适用在哪些类型的网页制作中.背景图片的 position 值如何确定以及制作 sprites 的技巧. [CSS sprites 简介] CSS Spri ...
- python【第十五篇】JavaScript
大纲 1 简介 2 存在形式 3 放置位置 4 变量 5 注释 6 数据类型 7 时间处理 8 语句和异常 9 函数及其作用域 1.JS简介 JavaScript是世界上最流行的脚本语言,因为你在电脑 ...
- 工欲善其事必先利其器-Notepad++使用小记(Python)
大学开始就一直使用Notepad++ 作为代码编辑器,喜欢它的简洁明了,喜欢它的个性,也喜欢它各种各样骚气的插件. 今天闲来无事,写篇文章记录一下平时使用的种种,包括但不限于个性化使用一些宏,快捷键, ...
- Java Learning:并发中的同步锁(synchronized)
引言 最近一段时间,实验室已经倾巢出动找实习了,博主也凑合了一把,结果有悲有喜,BAT理所应当的跪了,也收到了其他的offer,总的感受是有必要夯实基础啊. 言归正传,最近在看到java多线程的时候, ...
- OpenCV for c++Builder
整理日: 20154/6 Borland C++BuilderでOpenCVを使う 確認 Turbo C++ 2007/03 1. ダウンロード&インストール http://sourcefor ...