SDWebImage笔记
SDWebImage托管在github上。https://github.com/rs/SDWebImage
这个类库提供一个UIImageView类别以支持加载来自网络的远程图片。具有缓存管理、异步下载、同一个URL下载次数控制和优化等特征。
使用示范的代码:
UITableView使用UIImageView+WebCache类(基本应用,UIImageView的一个category)
前提#import导入UIImageView+WebCache.h文件,然后在tableview的cellForRowAtIndexPath:方法下:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
}
// Here we use the new provided setImageWithURL: method to load the web image
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
cell.textLabel.text = @"My Text";
return cell;
}
基本代码:[imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/image.jpg"]];
使用SDWebImageManager类:可以进行一些异步加载的工作。
SDWebImageManager *manager = [SDWebImageManager sharedManager];
UIImage *cachedImage = [manager imageWithURL:url]; // 将需要缓存的图片加载进来
if (cachedImage) {
// 如果Cache命中,则直接利用缓存的图片进行有关操作
// Use the cached image immediatly
} else {
// 如果Cache没有命中,则去下载指定网络位置的图片,并且给出一个委托方法
// Start an async download
[manager downloadWithURL:url delegate:self];
}
当然你的类要实现SDWebImageManagerDelegate协议,并且要实现协议的webImageManager:didFinishWithImage:方法。
// 当下载完成后,调用回调方法,使下载的图片显示
- (void)webImageManager:(SDWebImageManager *)imageManager didFinishWithImage:(UIImage *)image {
// Do something with the downloaded image
}
独立的异步图像下载
可能会单独用到异步图片下载,则一定要用downloaderWithURL:delegate:来建立一个SDWebImageDownloader实例。
downloader = [SDWebImageDownloader downloaderWithURL:url delegate:self];
这样SDWebImageDownloaderDelegate协议的方法imageDownloader:didFinishWithImage:被调用时下载会立即开始并完成。
独立的异步图像缓存
SDImageCache类提供一个创建空缓存的实例,并用方法imageForKey:来寻找当前缓存。
UIImage *myCachedImage = [[SDImageCache sharedImageCache] imageFromKey:myCacheKey];
存储一个图像到缓存是使用方法storeImage: forKey:
[[SDImageCache sharedImageCache] storeImage:myImage forKey:myCacheKey];
默认情况下,图像将被存储在内存缓存和磁盘缓存中。如果仅仅是想内存缓存中,要使用storeImage:forKey:toDisk:方法的第三个参数带一负值
来替代。
SDWebImage 支持异步的图片下载+缓存,提供了 UIImageView+WebCacha 的 category,方便使用。纪录一下 SDWebImage 加载图片的流程。
- 入口 setImageWithURL:placeholderImage:options: 会先把 placeholderImage 显示,然后 SDWebImageManager 根据 URL 开始处理图片。
- 进入 SDWebImageManager-downloadWithURL:delegate:options:userInfo:,交给 SDImageCache 从缓存查找图片是否已经下载 queryDiskCacheForKey:delegate:userInfo:.
- 先从内存图片缓存查找是否有图片,如果内存中已经有图片缓存,SDImageCacheDelegate 回调 imageCache:didFindImage:forKey:userInfo: 到 SDWebImageManager。
- SDWebImageManagerDelegate 回调 webImageManager:didFinishWithImage: 到 UIImageView+WebCache 等前端展示图片。
- 如果内存缓存中没有,生成 NSInvocationOperation 添加到队列开始从硬盘查找图片是否已经缓存。
- 根据 URLKey 在硬盘缓存目录下尝试读取图片文件。这一步是在 NSOperation 进行的操作,所以回主线程进行结果回调 notifyDelegate:。
- 如果上一操作从硬盘读取到了图片,将图片添加到内存缓存中(如果空闲内存过小,会先清空内存缓存)。SDImageCacheDelegate 回调 imageCache:didFindImage:forKey:userInfo:。进而回调展示图片。
- 如果从硬盘缓存目录读取不到图片,说明所有缓存都不存在该图片,需要下载图片,回调 imageCache:didNotFindImageForKey:userInfo:。
- 共享或重新生成一个下载器 SDWebImageDownloader 开始下载图片。
- 图片下载由 NSURLConnection 来做,实现相关 delegate 来判断图片下载中、下载完成和下载失败。
- connection:didReceiveData: 中利用 ImageIO 做了按图片下载进度加载效果。
- connectionDidFinishLoading: 数据下载完成后交给 SDWebImageDecoder 做图片解码处理。
- 图片解码处理在一个 NSOperationQueue 完成,不会拖慢主线程 UI。如果有需要对下载的图片进行二次处理,最好也在这里完成,效率会好很多。
- 在主线程 notifyDelegateOnMainThreadWithInfo: 宣告解码完成,imageDecoder:didFinishDecodingImage:userInfo: 回调给 SDWebImageDownloader。
- imageDownloader:didFinishWithImage: 回调给 SDWebImageManager 告知图片下载完成。
- 通知所有的 downloadDelegates 下载完成,回调给需要的地方展示图片。
- 将图片保存到 SDImageCache 中,内存缓存和硬盘缓存同时保存。写文件到硬盘也在以单独 NSInvocationOperation 完成,避免拖慢主线程。
- SDImageCache 在初始化的时候会注册一些消息通知,在内存警告或退到后台的时候清理内存图片缓存,应用结束的时候清理过期图片。
- SDWI 也提供了 UIButton+WebCache 和 MKAnnotationView+WebCache,方便使用。
- SDWebImagePrefetcher 可以预先下载图片,方便后续使用。
SDWebImage库的作用:
通过对UIImageView的类别扩展来实现异步加载替换图片的工作。
主要用到的对象:
1、UIImageView (WebCache)类别,入口封装,实现读取图片完成后的回调
2、SDWebImageManager,对图片进行管理的中转站,记录那些图片正在读取。
向下层读取Cache(调用SDImageCache),或者向网络读取对象(调用SDWebImageDownloader) 。
实现SDImageCache和SDWebImageDownloader的回调。
3、SDImageCache,根据URL的MD5摘要对图片进行存储和读取(实现存在内存中或者存在硬盘上两种实现)
实现图片和内存清理工作。
4、SDWebImageDownloader,根据URL向网络读取数据(实现部分读取和全部读取后再通知回调两种方式)
其他类:
SDWebImageDecoder,异步对图像进行了一次解压⋯⋯
目前不明白为什么要做这么道工序。(现在清楚了,功能解释见下文)
有趣的点:
1、SDImageCache是怎么做数据管理的?
SDImageCache分两个部分,一个是内存层面的,一个是硬盘层面的。
内存层面的相当是个缓存器,以Key-Value的形式存储图片。当内存不够的时候会清除所有缓存图片。
用搜索文件系统的方式做管理,文件替换方式是以时间为单位,剔除时间大于一周的图片文件。
当SDWebImageManager向SDImageCache要资源时,先搜索内存层面的数据,如果有直接返回,没有的话去访问磁盘,将图片从磁盘读取出来,然后做Decoder,将图片对象放到内存层面做备份,再返回调用层。
2、为啥必须做Decoder?
通过这个博客:http://www.cocoanetics.com/2011/10/avoiding-image-decompression-sickness/
现在明白了,由于UIImage的imageWithData函数是每次画图的时候才将Data解压成ARGB的图像,
所以在每次画图的时候,会有一个解压操作,这样效率很低,但是只有瞬时的内存需求。
为了提高效率通过SDWebImageDecoder将包装在Data下的资源解压,然后画在另外一张图片上,这样这张新图片就不再需要重复解压了。
这种做法是典型的空间换时间的做法
SDWebImage笔记的更多相关文章
- iOS第三方网络图片加载- SDWebImage笔记(转)
SDWebImage托管在github上.https://github.com/rs/SDWebImage 这个类库提供一个UIImageView类别以支持加载来自网络的远程图片.具有缓存管理.异步下 ...
- IOS开发笔记 - 基于SDWebImage的网络图片加载处理
前言: 在IOS下通过URL读一张网络图片并不像Asp.net那样可以直接把图片路径放到图片路径的位置就ok, 而是需要我们通过一段类似流的方式去加载网络图片,接着才能把图片放入图片路径显示. 这里找 ...
- 离屏渲染学习笔记 /iOS圆角性能问题
离屏渲染学习笔记 一.概念理解 OpenGL中,GPU屏幕渲染有以下两种方式: On-Screen Rendering 意为当前屏幕渲染,指的是GPU的渲染操作是在当前用于显示的屏幕缓冲区中进行. O ...
- iOS开发笔记7:Text、UI交互细节、两个动画效果等
Text主要总结UILabel.UITextField.UITextView.UIMenuController以及UIWebView/WKWebView相关的一些问题. UI细节主要总结界面交互开发中 ...
- [置顶] iOS学习笔记47——图片异步加载之EGOImageLoading
上次在<iOS学习笔记46——图片异步加载之SDWebImage>中介绍过一个开源的图片异步加载库,今天来介绍另外一个功能类似的EGOImageLoading,看名字知道,之前的一篇学习笔 ...
- 阅读Facebook POP框架 笔记(一)
在这一系列文章里,我主要会将自己阅读第三方代码的经历记录下来,尝试独立分析解剖一个框架.之前也阅读过一些第三方代码,但是实际上来说对自己的成长并没有太大的帮助,因为阅读的不细致,没有领会到代码的精髓. ...
- cocoa pods自己的笔记
备注:这里只是个人的观点,有的地方也是copy,多多指教,个人笔记,有侵犯你们版权的地方还望海涵!!! 卡主不动 安装流程:http://www.tuicool.com/articles/qaMfuy ...
- iOS学习笔记之异步图片下载
写在前面 在iOS开发中,无论是在UITableView还是在UICollectionView中,通过网络获取图片设置到cell上是较为常见的需求.尽管有很多现存的第三方库可以将下载和缓存功能都封装好 ...
- iOS学习笔记13-网络(二)NSURLSession
在2013年WWDC上苹果揭开了NSURLSession的面纱,将它作为NSURLConnection的继任者.现在使用最广泛的第三方网络框架:AFNetworking.SDWebImage等等都使用 ...
随机推荐
- 【SSH】 之 Struts
(一)什么是Struts,Struts是什么? Struts是学习轻量级J2EE框架所必须要了解的一个框架,也是我们当前最最流行的三大框架(SSH——Struts,Spring,Hibernate)之 ...
- SQL Server 创建表 添加主键 添加列常用SQL语句
--删除主键 alter table 表名 drop constraint 主键名 --添加主键 alter table 表名 add constraint 主键名 primary key(字段名1, ...
- Android自动化测试之Monkey Test 安装(二)
因为Monkey Test是在eclipse上执行的,所以玩monkey test的时候要先配置安卓开发环境 一.Android开发环境搭建指南 1.安装JDK JDK下载链接:http://www. ...
- 在Activity中响应ListView内部按钮的点击事件
最近交流群里面有人问到一个问题:如何在Activity中响应ListView内部按钮的点击事件,不要在Adapter中响应? 对于这个问题,我最初给他的解答是,在Adapter中定义一个回调接口,在A ...
- 在CentOS中快速安装PHP,MySQL,Nginx和phpMyAdmin
安装环境 yum install -y autoconf automake gcc gcc-c++ git libtool make nasm pkgconfig zlib-devel vim 安装p ...
- Http协议提要
HTTP协议提要 简单来说,HTTP就是一个基于应用层的通信规范:双方要进行通信,大家就要遵守一个规范---HTTP协议.HTTP协议从WWW服务器超文本到本地浏览器 ,可以使浏览器更加高效.HTTP ...
- DSP using MATLAB 示例Example3.22
代码: % Discrete-time Signal x2(n) Ts = 0.001; n = -5:1:5; nTs = n*Ts; Fs = 1/Ts; x = exp(-1000*abs(nT ...
- node.js整理 01代码的组织和部署
模块 require(函数) 用于在当前模块中加载和使用别的模块,传入一个模块名,返回一个模块导出对象. 模块名可使用相对路径(以./开头),或者是绝对路径(以/或C:之类的盘符开头:注意单个模块名默 ...
- Java 程序员们值得一看的好书推荐[转载]
“学习的最好途径就是看书“,这是我自己学习并且小有了一定的积累之后的第一体会.个人认为看书有两点好处: 能出版出来的书一定是经过反复的思考.雕琢和审核的,因此从专业性的角度来说,一本好书的价值远超其他 ...
- jQuery Cycle Plugin的使用
jQuery幻灯片效果或者Slideshow效果当中如果不考虑touch效果的话,jQuery Cycle插件实在是太强大了,各种高大上的动画效果,如果想加上touch效果可以结合本blog介绍的wi ...