SDWebImage总结

SDWebImage

支持异步的图片下载+缓存,提供了 UIImageView+WebCache的 category,方便使用。

优点:首先NSURLCache是缓存原始数据(raw data)到磁盘或内存,因此每次使用的时候需要将原始数据转换成具体的对象,如UIImage等,这会导致额外的数据解析以及内存占用等,而SDWebImage则是缓存UIImage对象在内存,缓存在NSCache中,同时直接保存压缩过的图片到磁盘中;还有一个问题是当你第一次在UIImageView中使用image对象的时候,图片的解码是在主线程中运行的!而SDWebImage会强制将解码操作放到子线程中。

记录一下 SDWebImage 加载图片的流程:

  1. 1 入口 setImageWithURL:placeholderImage:options: 会先把 placeholderImage 显示,然后 SDWebImageManager 根据 URL 开始处理图片。
  2. 2 进入 SDWebImageManager-downloadWithURL:delegate:options:userInfo:,交给 SDImageCache 从缓存查找图片是否已经下载 queryDiskCacheForKey:delegate:userInfo:.
  3. 3 先从内存图片缓存查找是否有图片,如果内存中已经有图片缓存,SDImageCacheDelegate 回调 imageCache:didFindImage:forKey:userInfo: 到 SDWebImageManager。
  4. 4 SDWebImageManagerDelegate 回调 webImageManager:didFinishWithImage: 到 UIImageView+WebCache 等前端展示图片。
  5. 5 如果内存缓存中没有,生成 NSInvocationOperation 添加到队列开始从硬盘查找图片是否已经缓存。
  6. 6 根据 URLKey 在硬盘缓存目录下尝试读取图片文件。这一步是在 NSOperation 进行的操作,所以回主线程进行结果回调 notifyDelegate:。
  7. 7 如果上一操作从硬盘读取到了图片,将图片添加到内存缓存中(如果空闲内存过小,会先清空内存缓存)。SDImageCacheDelegate 回调 imageCache:didFindImage:forKey:userInfo:。进而回调展示图片。
  8. 8 如果从硬盘缓存目录读取不到图片,说明所有缓存都不存在该图片,需要下载图片,回调 imageCache:didNotFindImageForKey:userInfo:。
  9. 9 共享或重新生成一个下载器 SDWebImageDownloader 开始下载图片。
  10. 10 图片下载由 NSURLConnection 来做,实现相关 delegate 来判断图片下载中、下载完成和下载失败。
  11. 11 connection:didReceiveData: 中利用 ImageIO 做了按图片下载进度加载效果。
  12. 12 connectionDidFinishLoading: 数据下载完成后交给 SDWebImageDecoder 做图片解码处理。
  13. 13 图片解码处理在一个 NSOperationQueue 完成,不会拖慢主线程 UI。如果有需要对下载的图片进行二次处理,最好也在这里完成,效率会好很多。
  14. 14 在主线程 notifyDelegateOnMainThreadWithInfo: 宣告解码完成,imageDecoder:didFinishDecodingImage:userInfo: 回调给 SDWebImageDownloader。
  15. 15 imageDownloader:didFinishWithImage: 回调给 SDWebImageManager 告知图片下载完成。
  16. 16 通知所有的 downloadDelegates 下载完成,回调给需要的地方展示图片。
  17. 17 将图片保存到 SDImageCache 中,内存缓存和硬盘缓存同时保存。写文件到硬盘也在以单独 NSInvocationOperation 完成,避免拖慢主线程。
  18. 18 SDImageCache 在初始化的时候会注册一些消息通知,在内存警告或退到后台的时候清理内存图片缓存,应用结束的时候清理过期图片。
  19. 19 SDWI 也提供了 UIButton+WebCache 和 MKAnnotationView+WebCache,方便使用。
  20. 20 SDWebImagePrefetcher 可以预先下载图片,方便后续使用。

SDWebImage库的作用:

通过对UIImageView的类别扩展来实现异步加载替换图片的工作。

主要用到的对象:

1UIImageView (WebCache)类别,入口封装,实现读取图片完成后的回调

2SDWebImageManager,对图片进行管理的中转站,记录那些图片正在读取。

向下层读取Cache(调用SDImageCache),或者向网络读取对象(调用SDWebImageDownloader)。

实现SDImageCacheSDWebImageDownloader的回调。

3SDImageCache,根据URLMD5摘要对图片进行存储和读取(实现存在内存中或者存在硬盘上两种实现)

实现图片和内存清理工作。

4SDWebImageDownloader,根据URL向网络读取数据(实现部分读取和全部读取后再通知回调两种方式)

其他类:

SDWebImageDecoder,异步对图像进行了一次解压……

目前不明白为什么要做这么道工序。(现在清楚了,功能解释见下文)

有趣的点:

1SDImageCache是怎么做数据管理的?

SDImageCache分两个部分,一个是内存层面的,一个是硬盘层面的。

内存层面的相当是个缓存器,以Key-Value的形式存储图片。当内存不够的时候会清除所有缓存图片。

用搜索文件系统的方式做管理,文件替换方式是以时间为单位,剔除时间大于一周的图片文件。

SDWebImageManagerSDImageCache要资源时,先搜索内存层面的数据,如果有直接返回,没有的话去访问磁盘,将图片从磁盘读取出来,然后做Decoder,将图片对象放到内存层面做备份,再返回调用层。

2、为啥必须做Decoder?

通过这个博客:http://www.cocoanetics.com/2011/10/avoiding-image-decompression-sickness/

现在明白了,由于UIImageimageWithData函数是每次画图的时候才将Data解压成ARGB的图像,所以在每次画图的时候,会有一个解压操作,这样效率很低,但是只有瞬时的内存需求。为了提高效率通过SDWebImageDecoder将包装在Data下的资源解压,然后画在另外一张图片上,这样这张新图片就不再需要重复解压了。这种做法是典型的空间换时间的做法。

(1)显示下载进度

 1 NSString *URLString = @"http://ww1.sinaimg.cn/bmiddle/bfc243a3gw1ezautzt7guj20ku0v978r.jpg";
 2     [self.iconView sd_setImageWithURL:[NSURL URLWithString:URLString] placeholderImage:nil options:SDWebImageProgressiveDownload progress:^(NSInteger receivedSize, NSInteger expectedSize) {
 3         /**
 4             receivedSize  前面总共接收了多少字节数
 5             expectedSize 服务器上面文件的总大小
 6          */
 7        CGFloat progress = (CGFloat)receivedSize / expectedSize; //0
 8         NSLog(@"下载进度---%f",progress);
 9     } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
10 }];

(2)使用SDManager来显示下载进度

 1  //1.创建一个Manager
 2     SDWebImageManager *manager =[SDWebImageManager sharedManager];
 3     //根据URLString去下载图片
 4      NSString *URLString = @"http://imgsrc.baidu.com/forum/w%3D580/sign=1c9daa96dbb44aed594ebeec831d876a/9661edf81a4c510f437c4bc66159252dd52aa553.jpg";
 5     __weak typeof(self) weakSelf = self;
 6     [manager downloadImageWithURL:[NSURL URLWithString:URLString] options:SDWebImageProgressiveDownload progress:^(NSInteger receivedSize, NSInteger expectedSize) {
 7         /**
 8          receivedSize  前面总共接收了多少字节数
 9          expectedSize 服务器上面文件的总大小
10          */
11         CGFloat progress = (CGFloat)receivedSize / expectedSize; //0
12         NSLog(@"下载进度---%f",progress);
13     } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
14         //NSLog(@"%@",image);
15         weakSelf.iconView.image = image;
16     }];
时间: 2024-10-11 16:12:10

SDWebImage总结的相关文章

李洪强详细介绍SDWebImage

SDWebImage是一个开源的第三方库,它提供了UIImageView的一个分类,以支持从远程服务器下载并缓存图片的功能.它具有以下功能: 提供UIImageView的一个分类,以支持网络图片的加载与缓存管理 一个异步的图片加载器 一个异步的内存+磁盘图片缓存 支持GIF图片 支持WebP图片 后台图片解压缩处理 确保同一个URL的图片不被下载多次 确保虚假的URL不会被反复加载 确保下载及缓存时,主线程不被阻塞 从github上对SDWebImage使用情况就可以看出,SDWebImage在

iOS之SDWebImage清理缓存

.找到 SDWebImage找到SDImageCache类 添加如下方法 - (float)checkTmpSize { float totalSize = 0; NSDirectoryEnumerator *fileEnumerator = [[NSFileManager defaultManager] enumeratorAtPath:_diskCachePath]; for (NSString *fileName in fileEnumerator) { NSString *filePat

多线程与网络之SDWebImage和NSCache

*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } a { color: #4183C4; } a.absent { color: #cc0000; } a.anchor { display: block; padding-left: 30px; margin-left: -30px; cursor: pointer; position: absolute

SDWebImage源码学习笔记

//  这是我第二次学习sdwebimage源码,第一次学习吸收的很少,看不懂啊.第二次看个50%,在此记录一点笔记. 首先是目录: 1.SDWebImage目录 里面有两个类,SDWebImageCompat.h 里面有个根据屏幕设置图片scale的方法 SDWebImageOperation.h 声明了一个协议,取消操作 (可以理解这一个放的公共方法目录) 2.Downloader 目录(顾名思义,下载操作相关的目录)里面有两个关键的类 SDWebImageDownloaderOperati

检测SDWebImage有没有缓存图片 IOS 获取网络图片大小

NSURL *url = [NSURL URLWithString:[model.content objectForKey:@"image"]];             //请求网络地址数据的同步方法             //因为这个方法在子线程(全局队列)中执行,所以不需要考虑死线程的问题             SDWebImageManager *manager = [SDWebImageManager sharedManager];              [manag

NSURLConnection / NSURLSession/ SDWebImage

1. NSURLConnection (iOS9开始被弃用)=========================================== 此类的对象加载一个URL请求对象,通过异步/同步的方式发送请求,并获得响应. 此类位于Foundation框架下,继承自NSObject ------------------------------ 异步/同步?    通讯方式 异步:在请求发送后,无需等待响应结果,而是可以继续后续其他操作,该请求的响应在回调方法中处理(通常用到的代理方法或bloc

SDWebImage使用,图片加载和缓存

SDWebImage使用,图片加载和缓存 2012-12-14 12:28:12|  分类: iOS|举报|字号 订阅 下载LOFTER我的照片书  | 清除缓存: [[SDImageCache sharedImageCache] clearDisk]; [[SDImageCache sharedImageCache] clearMemory]; 来自:http://blog.csdn.net/sqc3375177/article/details/7714573 SDWebImage托管在git

iOS之SDWebImage的使用

第一步,下载SDWebImage,导入工程.github托管地址https://github.com/rs/SDWebImage 第二步,在需要的地方导入头文件 1 #import "UIImageView+WebCache.h" 第三步,调用sd_setImageWithURL:方法缓存图片,注意,这就是新版本的新方法,旧方法是setImageWithURL:.下面将几个方法都介绍一下. 1. sd_setImageWithURL: 1 2 //图片缓存的基本代码,就是这么简单   

iOS 用 SDWebImage 清理图片缓存

转自:http://www.cnblogs.com/qianLL/p/5389079.html 具体效果如下 1.找到 SDWebImage找到SDImageCache类 添加如下方法 - (float)checkTmpSize { float totalSize = 0; NSDirectoryEnumerator *fileEnumerator = [[NSFileManager defaultManager] enumeratorAtPath:_diskCachePath]; for (N

使用SDWebImage加载大量图片后造成内存泄露的解决办法 转载

使用SDWebImage加载大量图片后造成内存泄露的解决办法 时间:2015-07-21 14:26:47      阅读:5885      评论:0      收藏:0      [点我收藏+] SDWebImage的知名度就不用说了,github上近10k的star,国内外太多的App使用其进行图片加载. 但是最近在使用过程中发现,在UITableView中不断加载更多的内容,使用SDWebImage会造成内存占用越来越大,导致memory warning最终terminate,稍微找了下