SDWebImage

作者: aSnail | 来源:发表于2015-10-22 21:38 被阅读1313次

SDWebImage

SDWebImage的简单介绍:一款世界级图片下载缓存框架,添加到工程中不会有烦人的警告

首先SDWebImage的实现原理

SDWebImageManger是由一个SDWebImageDownloader(负责下载网络图片),SDImageCache(一个处理缓存的类)共同构成的类

SDWebImage提供了如下三个category来进行缓存。
MKAnnotationView + WebCache 地图大头针
UIButton + WebCache 给按钮设置图片
UIImageView + WebCache imageView的图片

SDWebImage的常用方法介绍
在给tableView设置图片时可以用到SDWebImage中

UIImageView + WebCache分类中下面一个重要的方法

- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;

这个方法在以前的版本中是没有sd_前缀的,里面的参数很容易理解,这里重点介绍一下options这个参数:
options是SDWebImageOptions类型的枚举类型,里面有10个选项,下面一一进行介绍

 SDWebImageRetryFailed = 1 << 0,      默认情况下,当一个 URL 下载失败,会将该 URL 放在黑名单中,不再尝试下载,当使用这个标记时就会 ,取消黑名单意思是即使下载失败也不会被加入黑名单
    SDWebImageLowPriority = 1 << 1,      默认情况下,在 UI 交互时也会启动图像下载, 当时用这个标记时, 用户拖动tableView时不会进行图片的下载,当没有交互时才会下载
    SDWebImageCacheMemoryOnly = 1 << 2,   此标记取消磁盘缓存,仅做内存缓存 
    SDWebImageProgressiveDownload = 1 << 3, 默认情况下,图像会在下载完成后一次性显示,  此标记允许渐进式下载,就像浏览器中那样,下载过程中,图像会逐步显示出来
    SDWebImageRefreshCached = 1 << 4,      磁盘缓存将由 NSURLCache 处理,而不是 SDWebImage,这会对性能有轻微的影响, 此选项有助于处理同一个请求 URL 的图像发生变化,  如果缓存的图像被刷新,会调用一次 completion block,并传递最终的图像,  仅在无法使用嵌入式缓存清理参数确定图像 URL 时,使用此标记
    SDWebImageContinueInBackground = 1 << 5,  在 iOS 4+,当 App 进入后台后仍然会继续下载图像。这是向系统请求额外的后台时间以保证下载请求完成的, 如果后台任务过期,请求将会被取消
    SDWebImageHandleCookies = 1 << 6,      处理保存在 NSHTTPCookieStore 中的 cookies
    SDWebImageAllowInvalidSSLCertificates = 1 << 7,  允许不信任的 SSL 证书,  可以出于测试目的使用,在正式产品中慎用
    SDWebImageHighPriority = 1 << 8,      默认情况下,图像会按照在队列中的顺序被加载,此标记会将它们移动到队列前部立即被加载,  而不是等待当前队列被加载,等待队列加载会需要一段时间
    SDWebImageDelayPlaceholder = 1 << 9,    默认情况下,在加载图像时,占位图像已经会被加载。而此标记会延迟加载占位图像,直到图像已经完成加载
    SDWebImageTransformAnimatedImage = 1 << 10,  通常不会在可动画的图像上调用 transformDownloadedImage 代理方法,因为大多数转换代码会破坏动画文件,  使用此标记尝试转换

以最为常用的UIImageView为例:
UIImageView+WebCache分类里面常用的方法:

setImageWithURL :placeholderImage: options:```
这个方法默认情况下先显示 `placeholderImage` ,同时由`SDWebImageManager `根据 URL 来在本地查找图片。

SDWebImageManager: downloadWithURL:delegate:options:userInfo:```
SDWebImageManager是将UIImageView+WebCacheSDImageCache链接起来的类,图片缓存是在内存缓存一份,在磁盘缓存一份.

SDImageCache: queryDiskCacheForKey:delegate:userInfo:

用来从缓存根据CacheKey查找图片是否已经在内存缓存中,如果内存中已经有图片缓存,SDWebImageManager会回调

SDImageCacheDelegate : imageCache:didFindImage:forKey:userInfo:

UIImageView+WebCache则回调

SDWebImageManagerDelegate: webImageManager:didFinishWithImage:```
来显示图片。
如果内存中没有图片缓存,那么生成 `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 `中完成,避免拖慢主线程。
如果是在iOS上运行,`SDImageCache` 在初始化的时候会注册`notification` 到 

UIApplicationDidReceiveMemoryWarningNotification

以及` UIApplicationWillTerminateNotification`,在内存警告的时候清理内存图片缓存,应用结束的时候清理过期图片。
`SDWebImagePrefetcher `可以预先下载图片,方便后续使用。
下面是`SDWebImage`在清理图片缓存时的原理
####使用SDWebImage设置cell图片(网上下载)的注意点

当程序收到内存警告的时候就会调用下面的方法


![screenshot.png](http:https://img.haomeiwen.com/i788734/08ba5945858af31e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
####SDWebImage在cleanMemary(清除缓存)时的运行原理
- 遍历缓存目录,删除所有过期图片
- 统计没有过期的图片的总大小
- 判断没有过期的图片的总大小是否超过了最大的缓存大小
- 如果过期图片超过缓存总大小就会继续删除没有过期的图片,从大到小的删除

相关文章

网友评论

    本文标题:SDWebImage

    本文链接:https://www.haomeiwen.com/subject/uasthttx.html