SDWebImage原理小结
首先,这个类库提供一个UIImageView类别以支持加载来自网络的远程图片。具有缓存管理、异步下载、同一个URL下载次数控制和优化等特征。
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) 。
4、SDWebImageDownloader,根据URL向网络读取数据(实现部分读取和全部读取后再通知回调两种方式)
其他类:
SDWebImageDecoder,异步对图像进行了一次解压⋯⋯
内存层面的相当是个缓存器,以Key-Value的形式存储图片。当内存不够的时候会清除所有缓存图片。
用搜索文件系统的方式做管理,文件替换方式是以时间为单位,剔除时间大于一周的图片文件。
当SDWebImageManager向SDImageCache要资源时,先搜索内存层面的数据,如果有直接返回,没有的话去访问磁盘,将图片从磁盘读取出来,然后做Decoder,将图片对象放到内存层面做备份,再返回调用层。
- (void)loadGIF
{
NSURL *URL;
// 加载网络gif图
URL = [NSURL URLWithString:@"http://image.nihaowang.com/news/2015-04-27/c30f866d-9300-4f6e-86f6-58f408630e14.gif"];
// 加载本地gif图
[self.imgView sd_setImageWithURL:URL];
}
- (void)loadProgress
{
NSURL *URL = [NSURL URLWithString:@"http://pic1.nipic.com/2008-11-13/2008111384358912_2.jpg"];
[self.imgView sd_setImageWithURL:URL placeholderImage:nil options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {
// receivedSize : 接收的图片大小
// expectedSize : 图片的总大小
float progress = (float)receivedSize / expectedSize;
NSLog(@"%zd %zd %f",receivedSize,expectedSize,progress);
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
NSLog(@"图片下载完成 %@",image);
}];
}
- (void)LoadImageWithManager
{
NSURL *URL = [NSURL URLWithString:@"http://pic37.nipic.com/20140209/8821914_163234218136_2.jpg"];
[[SDWebImageManager sharedManager] downloadImageWithURL:URL options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {
// receivedSize : 接收的图片大小
// expectedSize : 图片的总大小
float progress = (float)receivedSize / expectedSize;
NSLog(@"%zd %zd %f",receivedSize,expectedSize,progress);
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
self.imgView.image = image;
}];
}
SDWebImage原理小结的更多相关文章
- Bagging与随机森林算法原理小结
在集成学习原理小结中,我们讲到了集成学习有两个流派,一个是boosting派系,它的特点是各个弱学习器之间有依赖关系.另一种是bagging流派,它的特点是各个弱学习器之间没有依赖关系,可以并行拟合. ...
- 梯度提升树(GBDT)原理小结
在集成学习之Adaboost算法原理小结中,我们对Boosting家族的Adaboost算法做了总结,本文就对Boosting家族中另一个重要的算法梯度提升树(Gradient Boosting De ...
- 集成学习之Adaboost算法原理小结
在集成学习原理小结中,我们讲到了集成学习按照个体学习器之间是否存在依赖关系可以分为两类,第一个是个体学习器之间存在强依赖关系,另一类是个体学习器之间不存在强依赖关系.前者的代表算法就是是boostin ...
- 梯度提升树(GBDT)原理小结(转载)
在集成学习值Adaboost算法原理和代码小结(转载)中,我们对Boosting家族的Adaboost算法做了总结,本文就对Boosting家族中另一个重要的算法梯度提升树(Gradient Boos ...
- XGBoost算法原理小结
在两年半之前作过梯度提升树(GBDT)原理小结,但是对GBDT的算法库XGBoost没有单独拿出来分析.虽然XGBoost是GBDT的一种高效实现,但是里面也加入了很多独有的思路和方法,值得单独讲一讲 ...
- K近邻法(KNN)原理小结
K近邻法(k-nearst neighbors,KNN)是一种很基本的机器学习方法了,在我们平常的生活中也会不自主的应用.比如,我们判断一个人的人品,只需要观察他来往最密切的几个人的人品好坏就可以得出 ...
- gc原理小结
一.相关概念 基本回收算法 1. 引用计数(Reference Counting) 比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收集计数为0 ...
- GBDT(梯度提升树) 原理小结
在之前博客中,我们对Boosting家族的Adaboost算法做了总结,本文就对Boosting家族中另一个重要的算法梯度提升树(Gradient Boosting Decison Tree, 以下简 ...
- SDWebImage 原理及使用问题
SDWebImage托管在github上.https://github.com/rs/SDWebImage 这个类库提供一个UIImageView类别以支持加载来自网络的远程图片.具有缓存管理.异步下 ...
随机推荐
- SQL Server执行计划
要理解执行计划,怎么也得先理解,那各种各样的名词吧.鉴于自己还不是很了解.本文打算作为只写懂的,不懂的懂了才写. 在开头要先说明,第一次看执行计划要注意,SQL Server的执行计划是从右向左看的. ...
- Things About 'extern'
Note: All Learned From Here C和Objective-C的function前面都有个隐含的extern,对于function来说,有没有extern都无所谓,但变量不一样. ...
- linq any()方法实现sql in()方法的效果
public IQueryable<Vsec009ComSecComp> QueryList(Sec009ComSecCompQueryCondition condition) { var ...
- qt5 基础知识
QWidget wQLineEdit edit; edit.show(); //如果没有这句,编辑框edit将会显示在父窗口的左上角edit.setParent(&w); //以w为父窗口并显 ...
- VPS用LNMP安装WordPress
前言 前几天,朋友手头上有一个空闲的vps,256M内存,我决定拿来玩一下.经过一番思考,还是用来挂站吧.然后看是CentOS6系统,果断决定用从来没玩过的LNMP.于是,百度.谷歌找教程,好多教程都 ...
- Linux发行版
Linux 发行版(英语:Linux distribution,也被叫做GNU/Linux 发行版),为一般用户预先集成好的Linux操作系统及各种应用软件.一般用户不需要重新编译,在直接安装之后,只 ...
- hibernate的formula如何使用
之前用过hibernate的formula记得很好用,但是这次用到想不起来怎么用了,结果去网上查结果发现大多都是无用信息. 最终搞定了,还是在这里记录一下,省的忘记. 我用formula的目的在于字典 ...
- 通过ip获取地理位置信息
http://ipinfo.io/developers 直接使用get请求 url: http://ipinfo.io/json 即可获得json数据
- mybatis源码分析(3)——SqlSessionManager类
从上图可能看出,在 mybatis中,SqlSession的实现类有两个,其中SqlSessionManager类不但实现了SqlSession接口,同时也实现了SqlSessionFactory接口 ...
- Hadoop RPC源码阅读-客户端
Hadoop版本Hadoop2.6 RPC主要分为3个部分:(1)交互协议(2)客户端(3)服务端 (2)客户端 先展示RPC客户端实例代码 public class LoginController ...