网络与多线程---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(私有的),具体的不同和特 ...
随机推荐
- SqlParameter防止SQL注入
SQL注入的解决方案有好几种,待我细细研究过之后逐一讲解. 方法一:SqlParameter方法 这里有一篇博客是详细介绍SqlParameter的,可以看看 点我 string sqlStr=&qu ...
- webGL和three.js的关系
如今浏览器的功能越来越强大,而且这些功能可能通过JavaScript直接调用.你可以用HTML5标签轻松地添加音频和视频,而且可以在HTML5画布上创建各种交互组件.现在这个功能集合里又有了一个新成员 ...
- Linux-Xshell会话保持
1.Xshell客户端设置 2.服务端设置 修改/etc/ssh/sshd_config文件,找到 ClientAliveInterval 0和ClientAliveCountMax 3并将注释符号( ...
- python 入门基础4 --数据类型及内置方法
今日目录: 零.解压赋值+for循环 一. 可变/不可变和有序/无序 二.基本数据类型及内置方法 1.整型 int 2.浮点型float 3.字符串类型 4.列表类型 三.后期补充内容 零.解压赋值+ ...
- Javascript - Vue - vue对象的生命周期
vue对象的生命周期 从vue的创建到销毁会经过一系列的事件,这是vue对象的生命周期. 创建期间的生命周期函数 <div id="box"> <h3 id ...
- C++笔试易错题集(持续更新)
1.如下代码输出结果是什么? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include<stdio.h> char *myString() { ...
- Replication监控及自动故障切换
首先在相应的机器上增加授权 GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.108' IDENTIFIED BY 'repl';GRANT RE ...
- MySQL用户密码过期登陆报错ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
今天接到主从复制失败告警,查看MySQL,发现MySQL能够登陆但是执行命令报错, ERROR 1820 (HY000): You must reset your password using ALT ...
- springcloud使用使用Feign-Ribbon做负载均衡实现声明式REST调用
什么是Feign Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单.使用Feign,只需要创建一个接口并注解.它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解 ...
- CF1063A 【Oh Those Palindromes】
考虑在一个部分串中加入字符使得最终构造的串回文子串最多的方案 考虑简单情况,对于只含一种元素的串,我们要插入其他元素 记原有元素为$a$,新加元素为$b$ 考虑$b$的最优插入位置 原串$aaaa.. ...