两种利用GCD实现分步获取结果的方式和SDWebImage缓存机制的验证
前段时间写界面,因为数据的请求分成了两部分,所以用到了多线程,实现数据的分步请求,然后自己写了一个Demo,用两种方式实现分步获取内容,其中也包含了验证SDWebImage这个库的缓存机制,在这里给大家分享一下,希望对大家有用,不喜勿喷~~
首先想要说的是GCD线程分步实现的过程,代码如下:(相关文字说明在代码中都包含)
#pragma mark --------- 并行异步执行的方法:利用GCD并行多个线程并且等待所有线程结束之后再执行其它方法
- (void)pushRequstData1 {
__weak typeof (self) selfVc = self;
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// 并行执行的线程一
NSLog(@"11111111");
[selfVc oneOne];
NSLog(@".........11111111");
});
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// 并行执行的线程二
NSLog(@"44444444");
[selfVc twoTwo];
NSLog(@".........22222222");
});
dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{
// 汇总结果
NSLog(@"这里可以最后刷新数据,更新界面。。。。77777777");
});
}
#pragma mark --------- 串行异步执行的方法:利用GCD串行多个线程,必须等到上一个完成之后,才能执行下一个任务,并且可以等待所有线程结束之后再执行其它方法
- (void)pushRequstData2 {
__weak typeof (self) selfVc = self;
//利用GCD串行多个线程,按顺序完成各个任务,并且等待所有线程结束之后再执行其它任务
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue1 = dispatch_queue_create("queue1", DISPATCH_QUEUE_SERIAL);
dispatch_group_async(group, queue1, ^{
// 串行执行的线程一
NSLog(@"11111111");
[selfVc oneOne];
});
dispatch_group_async(group, queue1, ^{
// 串行执行的线程二
NSLog(@"44444444");
[selfVc twoTwo];
});
dispatch_group_notify(group, queue1, ^{
// 汇总结果
NSLog(@"这里可以最后刷新数据,更新界面。。。。77777777");
});
}
//方法执行
/*注意:
1.注意循环引用的问题,如果有用到self,要使用弱引用:__weak typeof (self) selfVc = self;这样效果最好,防止循环引用的问题
*/
//[self pushRequstData1];//这个是并行异步的方法,oneOne和twoTwo方法会同时进行,所以执行的顺序不是1234567
[self pushRequstData2];//这个是串行异步执行的方法,会等线程一执行完成,才会执行线程二,所以执行的顺序是1234567
接下来就是验证SDWebImage缓存图片的代码,突发奇想写这个是因为,看到支付宝,爱奇艺等相关APP,在不连接网络的情况下还会显示图片,所以为了实现这一效果和验证缓存机制,写了这些代码,希望对大家有帮助,代码如下:
/**
验证步骤:
1:首先连接网络运行APP,并显示图片;
2:结束APP,退出程序,记得双击home键,把此APP进程删除;
3:关闭网络,运行APP,并进入显示图片的界面,发现在没有网络的情况下,之前通过网络请求的图片显示了,说明SDWebImage已经把图片下载进行了缓存。
**/
//添加图片
-(void)addImgV:(NSArray *)arr
{
if (arr.count<=0) {
_dataArray = [NSArray arrayWithContentsOfFile:[self saveLocalPath:@"dataStr1"]];
}else{
//存入本地,方便没网时,读取缓存在本地的图片文件
_dataArray = [NSArray arrayWithArray:arr];
[_dataArray writeToFile:[self saveLocalPath:@"dataStr1"] atomically:YES];
}
for (int i = 0; i < _dataArray.count; i++) {
NSDictionary *dic = _dataArray[i];
UIImageView *imgV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 100+i*130, 200, 120)];
[imgV sd_setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://image.healthmanage.cn/qImage/%@",dic[@"imagePath"]]] placeholderImage:[UIImage imageNamed:@"guanggao.png"]];
[self.view addSubview:imgV];
}
}
//缓存到本地的数据方法,强烈建议创建的文件名称使用宏定义方式,以防拼写或读取数据时出错
-(NSString *)saveLocalPath:(NSString *)strPath
{
NSArray *arr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPathStr = arr[0];
NSString *dataPathStr = [documentPathStr stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist",strPath]];
return dataPathStr;
}
SDWebImage的原理:
1、入口 setImageWithURL:placeholderImage:options: 会先把 placeholderImage 显示,然后 SDWebImageManager 根据 URL 开始处理图片。
2、进入 SDWebImageManager-downloadWithURL:delegate:options:userInfo:,交给 SDImageCache 从缓存查找图片是否已经下载 queryDiskCacheForKey:delegate:userInfo:.
3、先从内存图片缓存查找是否有图片,如果内存中已经有图片缓存,SDImageCacheDelegate 回调 imageCache:didFindImage:forKey:userInfo: 到 SDWebImageManager。
4、SDWebImageManagerDelegate 回调 webImageManager:didFinishWithImage: 到 UIImageView+WebCache 等前端展示图片。
5、如果内存缓存中没有,生成 NSInvocationOperation 添加到队列开始从硬盘查找图片是否已经缓存。
6、根据 URLKey 在硬盘缓存目录下尝试读取图片文件。这一步是在 NSOperation 进行的操作,所以回主线程进行结果回调 notifyDelegate:。
7、如果上一操作从硬盘读取到了图片,将图片添加到内存缓存中(如果空闲内存过小,会先清空内存缓存)。SDImageCacheDelegate 回调 imageCache:didFindImage:forKey:userInfo:。进而回调展示图片。
8、如果从硬盘缓存目录读取不到图片,说明所有缓存都不存在该图片,需要下载图片,回调 imageCache:didNotFindImageForKey:userInfo:。
9、共享或重新生成一个下载器 SDWebImageDownloader 开始下载图片。
10、图片下载由 NSURLConnection 来做,实现相关 delegate 来判断图片下载中、下载完成和下载失败。
11、connection:didReceiveData: 中利用 ImageIO 做了按图片下载进度加载效果。
12、connectionDidFinishLoading: 数据下载完成后交给 SDWebImageDecoder 做图片解码处理。
13、图片解码处理在一个 NSOperationQueue 完成,不会拖慢主线程 UI。如果有需要对下载的图片进行二次处理,最好也在这里完成,效率会好很多。
14、在主线程 notifyDelegateOnMainThreadWithInfo: 宣告解码完成,imageDecoder:didFinishDecodingImage:userInfo: 回调给 SDWebImageDownloader。
15、imageDownloader:didFinishWithImage: 回调给 SDWebImageManager 告知图片下载完成。
16、通知所有的 downloadDelegates 下载完成,回调给需要的地方展示图片。
17、将图片保存到 SDImageCache 中,内存缓存和硬盘缓存同时保存。写文件到硬盘也在以单独 NSInvocationOperation 完成,避免拖慢主线程。
18、SDImageCache 在初始化的时候会注册一些消息通知,在内存警告或退到后台的时候清理内存图片缓存,应用结束的时候清理过期图片。
19、SDWI 也提供了 UIButton+WebCache 和 MKAnnotationView+WebCache,方便使用。
20、SDWebImagePrefetcher 可以预先下载图片,方便后续使用。
相关代码,请自行研究,很简单(源码:https://github.com/hbblzjy/OCGCDMoreDispath)
两种利用GCD实现分步获取结果的方式和SDWebImage缓存机制的验证的更多相关文章
- 在ASP.Net中两种利用CSS实现多界面的方法
通过使页面动态加载不同CSS实现多界面(类型于csdn的blog): 方法一: <%@page language="C#"%><%@import namespac ...
- QT中获取选中的radioButton的两种方法(动态取得控件的objectName之后,对名字进行比较)
QT中获取选中的radioButton的两种方法 QT中要获取radioButton组中被选中的那个按钮,可以采用两种如下两种办法进行: 方法一:采用对象名称进行获取 代码: 1 QRadioBu ...
- Java 爬虫遇上数据异步加载,试试这两种办法!
这是 Java 爬虫系列博文的第三篇,在上一篇 Java 爬虫遇到需要登录的网站,该怎么办? 中,我们简单的讲解了爬虫时遇到登录问题的解决办法,在这篇文章中我们一起来聊一聊爬虫时遇到数据异步加载的问题 ...
- Android中BroadcastReceiver的两种注册方式(静态和动态)详解
今天我们一起来探讨下安卓中BroadcastReceiver组件以及详细分析下它的两种注册方式. BroadcastReceiver也就是"广播接收者"的意思,顾名思义,它就是用来 ...
- lucene的两种分页操作
基于lucene的分页有两种: lucene3.5之前分页提供的方式为再查询方式(每次查询全部记录,然后取其中部分记录,这种方式用的最多),lucene官方的解释:由于我们的速度足够快.处理海量数据时 ...
- JFreeChart与AJAX+JSON+ECharts两种处理方式生成热词统计可视化图表
本篇的思想:对HDFS获取的数据进行两种不同的可视化图表处理方式.第一种JFreeChar可视化处理生成图片文件查看.第二种AJAX+JSON+ECharts实现可视化图表,并呈现于浏览器上. 对 ...
- SAPUI5 freestyle vs SAP Fiori Elements —— 两种开发SAP UI5 Apps的方式对比
概述 目前SAPUI5 SDK 提供了两种方式来开发一个SAPUI5 App.一种方式是传统的SAPUI5开发方式,一种是利用SAP Fiori Elements通过模板快速构建应用的方式. 本文简单 ...
- 使用Python生成源文件的两种方法
利用Python的字符串处理模块,开发者能够编写脚本用来生成那些格式同样的C.C++.JAVA源程序.头文件和測试文件,从而避免大量的反复工作. 本文概述两种利用Python string类生成jav ...
- FTP两种工作模式:主动模式(Active FTP)和被动模式
在主动模式下,FTP客户端随机开启一个大于1024的端口N向服务器的21号端口发起连接,然后开放N+1号端口进行监听,并向服务器发出PORT N+1命令.服务器接收到命令后,会用其本地的FTP数据端口 ...
随机推荐
- JSONObject和JSONArray区别及基本用法
一.JSONObject和JSONArray的数据表示形式 JSONObject的数据是用 { } 来表示的, 例如: { "id" : "123", & ...
- windows平台安装maven
Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具. 一.安装maven3.5.3 安装环境(条件):Windows10.jdk1.7+ 1.下载m ...
- [LeetCode] 4 Keys Keyboard 四键的键盘
Imagine you have a special keyboard with the following keys: Key 1: (A): Print one 'A' on screen. Ke ...
- 【linux之crontab,启动】
一.计划任务 atd at命令发布的任务计划 一次性的任务计划 at time ctrl+d 提交 time: 1.绝对时间:12:00 2.相对时间:+8 3.模糊时间:noon midnight ...
- 计蒜客NOIP模拟赛4 D1T2小X的密室
小 X 正困在一个密室里,他希望尽快逃出密室. 密室中有 N 个房间,初始时,小 X 在 1 号房间,而出口在 N 号房间. 密室的每一个房间中可能有着一些钥匙和一些传送门,一个传送门会单向地创造一条 ...
- [UOJ]#36. 【清华集训2014】玛里苟斯
题目大意:给n个数字,求子集的异或和的k次方的期望(n<=10^5,k<=5,保证答案小于2^63) 做法:首先如果从集合中拿出a和b,把a和a xor b放回集合,子集的异或和与原来是一 ...
- ●HDU 3689 Infinite monkey theorem
题链: http://acm.hdu.edu.cn/showproblem.php?pid=3689题解: KMP,概率dp (字符串都从1位置开始) 首先对模式串S建立next数组. 定义dp[i] ...
- ●HDU 4787 GRE Words Revenge
题链: http://acm.hdu.edu.cn/showproblem.php?pid=4787 题解: AC自动机(强制在线构造) 题目大意: 有两种操作, 一种为:+S,表示增加模式串S, 另 ...
- Codeforces Round #452 F. Letters Removing
Description Petya has a string of length n consisting of small and large English letters and digits. ...
- Codeforces Round #403 (Div. 1, based on Technocup 2017 Finals)
Div1单场我从来就没上过分,这场又剧毒,半天才打出B,C挂了好几次最后还FST了,回紫了. AC:AB Rank:340 Rating:2204-71->2133 Div2.B.The Mee ...