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.运行任 ...
随机推荐
- [GDI+] C# ImageDown帮助类教程与源码下载 (转载)
点击下载 ImageDown.zip 1.下载图片到本地代码如下 /// <summary> /// 编 码 人:苏飞 /// 联系方式:361983679 /// 更新网站:[url=h ...
- A题笔记(2)
No. 1505 文件读相关 #include <fstream> #include <sstream> <fstream>支持文件的IO <sstream& ...
- xml处理相关文章收藏
XPath语法 在C#中使用XPath示例:http://blog.csdn.net/yukaizhao/article/details/6630613 .Net那点事儿系列:C#操作Xml:通过Xm ...
- OC细节 - 1.深拷贝与浅拷贝详解
概述 拷贝:复制一个与源对象内容相同的对象 实现拷贝,需要遵守以下两个协议 NSCopying NSMutableCopying 拷贝返回对象的种类 可变,mutableCopy消息返回的对象 不可变 ...
- java获取远程网络图片文件流、压缩保存到本地
1.获取远程网路的图片 /** * 根据地址获得数据的字节流 * * @param strUrl * 网络连接地址 * @return */ public static byte[] getImage ...
- html中子div用了浮动怎样让父div的大小自动撑开(清除浮动)
浮动子div撑开父div的几种方法: (1)在父div中在添加一个清除浮动的子div<div style=" clear:both;"></div>,该di ...
- 十进制和n进制的转换(10进制转换为36进制)
答案如下: void Convert() { map<int ,string> maps; maps[0]="0"; maps[1]="1"; ma ...
- Android Studio HelloWorld
开发第一应用 可以开发属于自己的应用,是否有点小激动?好吧!让我们开始,首先点击Start a new Android Studio Project创建工程: 接下来需要输入应用名称(第一个字母要大写 ...
- iOS:翻页效果
// // main.m // Hello // // Created by lishujun on 14-8-28. // Copyright (c) 2014年 lishujun. All rig ...
- 转载:如何避免代码中的if嵌套
http://top.jobbole.com/4960/ http://stackoverflow.com/questions/24430504/how-to-avoid-if-chains 在Sta ...