网络与多线程---OC中多线程方法GCD(二)
小编在前一篇中介绍了多线程实现的五种常用方法。在接下来所介绍的这种方法是最具有魅力的,最具有诱惑的实现多线程的方案---GCD
一、什么是GCD
GCD是Grand Central Dispatch的简称,是基于C语言的。如果使用GCD,完全由系统管理线程,我们不需要编写线程代码。只需定义想要执行的任务,然后添加到适当的调度队列(dispatch queue)。GCD会负责创建线程和调度你的任务,系统直接提供线程管理,大大的提高代码的执行效率与多核的利用率。
1.GCD的一个重要概念是队列,它的核心理念:将长期运行的任务拆分成多个工作单元,并将这些单元添加到dispath queue中,系统会为我们管理这些dispath queue,为我们在多个线程上执行工作单元,我们不需要直接启动和管理后台线程。
2.系统提供了许多预定义的dispath queue,包括可以保证始终在主线程上执行工作的dispath queue。也可以创建自己的dispath queue,而且可以创建任意多个。GCD的dispath queue严格遵循FIFO(先进先出)原则,添加到dispath queue的工作单元将始终按照加入dispath queue的顺序启动。
3.dispatch queue按先进先出的顺序,串行或并发地执行任务
二、创建和管理GCD
并发dispatch queue可以同时并行地执行多个任务,不过并发queue仍然按先进先出的顺序来启动任务。并发queue会在之前的任务完成之前就出列下一个任务并开始执行。并发queue同时执行的任务数量会根据应用和系统动态变化,各种因素包括:可用核数量、其它进程正在执行的工作数量、其它串行dispatch queue中优先任务的数量等.
//创建一个队列
dispatch_queue_attr_t queue = dispatch_queue_create("test", NULL);
/********此种方式是异步多线程的运行*********/
dispatch_async(queue, ^{
for (int i = ; i < ; i++) {
NSLog(@"---这是多线程---%d",i);
} //回到主线程
dispatch_sync(dispatch_get_main_queue(), ^{
BOOL isMain = [NSThread isMainThread];
if (isMain) {
NSLog(@"isMain");
}
});
}); /********此种方式是同步多线程的运行*********/
dispatch_sync(queue, ^{
//demo
});
GCD提供了函数让应用访问几个公共dispatch queue:
1>
使用dispatch_get_current_queue函数作为调试用途,或者测试当前queue的标识。在block对象中调用这个函数会返回
block提交到的queue(这个时候queue应该正在执行中)。在block对象之外调用这个函数会返回应用的默认并发queue。
2> 使用dispatch_get_main_queue函数获得应用主线程关联的串行dispatch queue
备注:在新创建的子线程中,需要添加自动释放池来管理内存。
GCD支持Cocoa内存管理机制,因此可以在提交到queue的 block中自由地使用Objective-C对象。每个dispatch queue维护自己的autorelease pool确保释放autorelease对象,但是queue不保证这些对象实际释放的时间。如果应用消耗大量内存,并且创建大量autorelease 对象,你需要创建自己的autorelease pool,用来及时地释放不再使用的对象。
三、暂停和继续queue
我们可以使用dispatch_suspend函数暂 停一个queue以阻止它执行block对象;使用dispatch_resume函数继续dispatch queue。调用dispatch_suspend会增加queue的引用计数,调用dispatch_resume则减少queue的引用计数。当引用 计数大于0时,queue就保持挂起状态。因此你必须对应地调用suspend和resume函数。挂起和继续是异步的,而且只在执行block之间(比 如在执行一个新的block之前或之后)生效。挂起一个queue不会导致正在执行的block停止。
四、案例
小编通过使用GCD的实现方法,通过URL来异步存储图片。
@implementation UIImageView (webCach)
- (void)setUIImageWithUrl:(NSURL*)url
{
//使用异步线程来下载
dispatch_queue_t queue = dispatch_queue_create("imageLoad", NULL);
dispatch_async(queue, ^{
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
//主线程
dispatch_sync(dispatch_get_main_queue(), ^{
self.image = image;
});
}); }
@end
- (void)viewDidLoad { [super viewDidLoad]; UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(, , , )];
[imageView setUIImageWithUrl:[NSURL URLWithString:@"http://s1.dwstatic.com/group1/M00/F5/00/f251b9aca3b84a55449f1083e9fe8cda.jpg"]];
[self.view addSubview:imageView]; }
当图片异步加载完成后,就会展现出来。但是,第二次进入该界面,还是要重新下载图片,用户体验不好,且浪费资源(比如耗电)。
于是,考虑缓存已经下载的图片。
小便的能力有限,欢迎大牛指正!!!
网络与多线程---OC中多线程方法GCD(二)的更多相关文章
- 网络与多线程---OC中多线程使用方法(一)
小编在此之前,通过一个小例子,简单的形容了一下进程与线程之间的关系,现在网络编程中的多线程说一下!!! *进程的基本概念 每一个进程都是一个应用程序,都有自己独立的内存空间,一般来说一个应用程序存在一 ...
- iOS开发——多线程OC篇&多线程中的单例
多线程中的单例 #import "DemoObj.h" @implementation DemoObj static DemoObj *instance; // 在iOS中,所有对 ...
- OC中property方法的使用
我们直入主题,关于property方法,我们先来了解一下相关的知识,首先是成员变量,实例变量,属性变量. 我们定义一个类来看一下 @interface Person :NSObject{ NSInte ...
- OC中多线程的一些概念
1.进程1.1>进程是指在系统中正在运行的一个应用程序(同时打开QQ和Xcode,系统会分别启动2个进程)1.2>每个进程之间是独立的,每个进程均运行在其专用的且受保护的内存空间内 2.线 ...
- iOS开发——多线程OC篇&多线程详解
多线程详解 前面介绍了多线程的各种方式及其使用,这里补一点关于多线程的概念及相关技巧与使用,相信前面不懂的地方看了这里之后你就对多线程基本上没有什么问题了! 1——首先ios开发多线程中必须了解的概念 ...
- iOS开发——多线程OC篇&多线程总结
多线程总结 //1.NSThread /** 优点:NSThread 比其他两个轻量级. 缺点:需要自己管理线程的生命周期,线程同步,线程同步时对数据的加锁会有一定的系统开销. cocoa给我提供了两 ...
- Python并发编程之创建多线程的几种方法(二)
大家好,并发编程 进入第二篇. 今天的内容会比较基础,主要是为了让新手也能无障碍地阅读,所以还是要再巩固下基础.学完了基础,你们也就能很顺畅地跟着我的思路理解以后的文章. 本文目录 学会使用函数创建多 ...
- OC中属性及方法
1.声明式属性 a.实例变量 b.声明属性 自动生成setter/getter方法 .h ->@property 属性类型 属性名; .m ...
- OC中实例变量可见度、setter、getter方法和自定义初始化方法
在对类和对象有一定了解之后,我们进一步探讨实例变量的可见度等相关知识 实例变量的可见度分为三种情况:public(共有),protected(受保护的,默认),private(私有的),具体的不同和特 ...
随机推荐
- python循环删除列表元素常见错误与正确方法
python循环删除列表元素 觉得有用的话,欢迎一起讨论相互学习~Follow Me 常见错误 常见错误一:使用固定长度循环删除列表元素 # 使用固定长度循环pop方法删除列表元素 num_list_ ...
- ifconfig不显示网卡eth0
参考资料:http://blog.itpub.net/25851087/viewspace-1700568/ 在/etc/sysconfig/network-script/ifcfg-eth0网卡配置 ...
- Java 在匿名内部函数中为外部函数变量赋值的解决方案
Java匿名内部函数本人不怎么主动使用,但是经常会调用一些API,其中会调用一些接口,而这些接口是需要使用匿名内部类来实现的,于是就遇到了一些问题. 就比如okHttp3 的接口调用 OkHttpCl ...
- bzoj千题计划238:bzoj3668: [Noi2014]起床困难综合症
http://www.lydsy.com/JudgeOnline/problem.php?id=3668 这..一位一位的来就好了呀 #include<cstdio> #include&l ...
- html5 canvas旋转+缩放
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 20155204 2016-2017-2 《Java程序设计》第8周学习总结
学号 2016-2017-2 <Java程序设计>第X周学习总结 教材学习内容总结 想要取得channel的操作对象,可以使用channels类,它定义了静态方法newChannel(). ...
- 【转】[.Net] 确定当前网站的物理文件路径
确定当前网站的物理文件路径 在应用程序中,您可能需要确定服务器上的文件或其他资源的路径.例如,如果应用程序以编程方式对文本文件进行读写操作,则必须为用于读取和写入的方法提供该文件的完整物理路径. 将物 ...
- Unable to Distribute in Xcode5?
Blog Unable to Distribute in Xcode5? I have the question, if this screenshot is what you getting. ( ...
- 使用Cobbler批量部署Linux和Windows:Cobbler服务端部署(一)
本文记录了我使用Cobbler批量安装部署Linux和Windows系统的过程,文章主要分为三部分:Cobbler服务端的安装配置.Linux发行版CentOS和Ubuntu的自动安装部署.Windo ...
- 20165230 2017-2018-2《Java程序设计》课程总结
20165230 2017-2018-2<Java程序设计>课程总结 一.作业链接汇总 每周作业链接 预备作业1:我期望的师生关系 预备作业2:做中学learning by doing个人 ...