1.什么是SDWebImage?
SDWebImage是iOS中一款功能很强大的处理图片的框架, 框架实现了异步加载网络图片、自动缓存图片数据等功能。使用它提供的方法, 一句话就能让 UIImageView 自动去加载并显示网络图片,它会自动去管理这些图片, 包括缓存到内存和缓存到磁盘等等。
2.以加载网络图片为例讲解“大致的原理过程”
- 注意:使用SDWebImage先要导入 #import "UIImageView+WebCache.h"头文件,设置网络图片的图片地址就可以加载图片,如下代码
NSURL *url = [NSURL URLWithString:@"http://b.hiphotos.baidu.com/imag1e03d003478ec54e736d196f9.jpg"];
[imageView sd_setImageWithURL:url placeholderImage:nil];
- 大致过程如下
屏幕快照 2017-12-06 下午12.02.01.png1.根据URL,SDWebImageManager类提供了方法,downloadWithURL加载图片,进入downloadWithURL方法,由SDImagerCache类提供方法queryDiskCacheForKey检查内存中是否有图片缓存,如果有则回调block将图片数据传递给SDWebImageManager类,SDWebImageManager类回调block将图片数据传递给UIImageView+WebCache类去显示图片。
2.如果内存中没有图片缓存,将会去磁盘中查找图片缓存。这一步操作是异步操作,如果从磁盘中读取到图片数据,将图片数据添加到内存缓存中,回调block将图片数据传递给SDWebImageManger类。 SDWebImageMange类回调block将图片数据传递给UIImageView+WebCache类去显示图片
3.内存和磁盘中都没有图片缓存,由SDWebImageDownloader类downloadImageWithUrl方法请求网络下载图片
4.图片和数据下载完成后交给 SDWebImageDecoder 做图片解码处理,图片解码完成后回调给SDWebImageDownloader类,SDWebImageDownloader类回调block将图片数据传递给SDWebImageManger类。 SDWebImageMange类回调block将图片数据传递给UIImageView+WebCache类显示图片。
5.图片数据会写入到内存和磁盘缓存中;该步操作是异步操作,避免拖慢主线程。
- 小结
1.SDWebImageManager *manager = [SDWebImageManager sharedManager];
这是管理图片的加载,由SDImagerCache类检查内存中是否有图片缓存,
或者由SDWebImageDownloader类请求网络下载图片。
2、SDImageCache 类管理图片缓存,读取图片缓存和写入图片缓存。
3、SDWebImageDownloader,根据URL向网络读取数据。
3.SDWebImage原理详解过程如下
1.入口setImageWithURL:placeholderImage:options: 会先把placeholdImage显示,然后SDWebImageManager根据URL开始处理图片
2.进入SDWebImageManager-downloadWithURL:delegate:options:userInfo:,交给SDWebImageCache从缓存查找图片是否已经下载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:宣告解码完成,ImageDownloader:didFinishDecodingImage:userInfo:回调给SDWebImageDownloader
15.imageDownloader:didFinishWithImage:回调给SDWebImageManager告知图片下载完成
16.通知所有的downloadDelegates下载完成,回调给需要的地方展示图片
17.将图片保存到SDImageCache中,内存缓存和硬盘缓存同时保存。写文件到硬盘也可以单独NSInvocationOperation完成,避免拖慢主线程
18.SDImageCache在初始化的时候会注册一些消息通知,在内存警告或退到后台的时候清理内存图片缓存,应用结束的时候清理过期的图片
19.SDWebImage提供了UIButton+WebCache和MKAnnotationView+WebCache,方便使用
20.SDWebImagePrefetcher可以预先下载图片,方便后续使用
4.总结SDWebImage库的作用
通过对UIImageView的类别扩展来实现一步加载替换图片的工作
主要用到的对象:
1.UIImageView(WebCache)类别,入口封装,实现读取图片完成后的回调
2.SDwebImageManager,对图片进行管理的中转站,记录哪些图片正在读取,向下层读取Cache
(调用SDImageCache),或者向网络读取对象(调用SDWebImageDownloader)。实现SDImageCache
和SDWebImageDownloader的回调
3.SDImageCache,根据URL的MD5摘要对图片进行存储和读取(实现存在内存中或者存在硬盘上两种实现)
实现图片和内存清理工作
4.SDWebImageDownloader,根据URL向网络读取数据(实现不分读取和全部读取后再通知回调两种方式)
5.SDWebImageDecoder,异步对图像进行一次解压由于。UIImage的imageWithData函数是每次画图的
时候才将Data解压成ARGB的图像,所以在每次画图的时候,会有一个解压操作,这样效率很低,但是只有
瞬时的内存需求。
6.为了提高效率通过SDWebImageDecoder将包装在Data下的资源解压,然后画在另外一张图片上,这样
这张新图片就不再需要重复解压了。这种做法是典型的空间换时间的做法。
优秀博客--iOS 图片加载框架SDWebImage详解🔗:http://blog.cocoachina.com/article/58823
网友评论