SDWebImage 实现原理
SDWebImage是个开源的图片加载框架,这个框架主要实现了两个功能:网络图片下载、网络图片缓存
一、主要实现类
- SDWebImageDownloader
- SDImageCache
- SDWebImageManager
SDWebImageDownloader 封装了下载图片的逻辑
SDImageCache 封装了图片缓存的逻辑
SDWebImageManager 用于管理图片的下载与缓存
二、SDWebImageDownloader 的实现
+ (id)downloaderWithURL:(NSURL *)url
delegate:(id<SDWebImageDownloaderDelegate>)delegate
userInfo:(id)userInfo
lowPriority:(BOOL)lowPriority;
+ (id)downloaderWithURL:(NSURL *)url
delegate:(id<SDWebImageDownloaderDelegate>)delegate
userInfo:(id)userInfo;
+ (id)downloaderWithURL:(NSURL *)url
delegate:(id<SDWebImageDownloaderDelegate>)delegate;
三个类方法:根据URL异步下载数据,通过代理监听下载完成的事件
三、SDImageCache的实现
将图片缓存到本地的三个方法,缓存的思路实现如下:
1、缓存分两种形式,内存缓存和磁盘缓存。
- 内存缓存:数据存到内存,下次需要用时,从内存中获取
- 磁盘缓存:数据存到磁盘上,下次从磁盘上读取这份数据
2、先将图片数据存到内存,然后将图片数据存到磁盘上,保存为一个文件,文件名是将URL经过MD5加密之后的字符串作为文件名
3、网络请求是对NSURLConnection进行了封装
- (void)storeImage:(UIImage *)image forKey:(NSString *)key;
- (void)storeImage:(UIImage *)image forKey:(NSString *)key
toDisk:(BOOL)toDisk;
- (void)storeImage:(UIImage *)image imageData:(NSData *)data
forKey:(NSString *)key
toDisk:(BOOL)toDisk;
从缓存中取数据的两个方法
1、先从内存中获取,看是否有该图片数据,有的话获取到
2、如果内存中无图片数据,则通过将URL经过MD5加密,作为文件名从磁盘读取获取图片数据
- (UIImage *)imageFromKey:(NSString *)key;
- (UIImage *)imageFromKey:(NSString *)key fromDisk:(BOOL)fromDisk;
四、SDWebImageManager 的实现
- (void)downloadWithURL:(NSURL *)url delegate:(id<SDWebImageManagerDelegate>)delegate;
- (void)downloadWithURL:(NSURL *)url delegate:(id<SDWebImageManagerDelegate>)delegate retryFailed:(BOOL)retryFailed;
- (void)downloadWithURL:(NSURL *)url delegate:(id<SDWebImageManagerDelegate>)delegate retryFailed:(BOOL)retryFailed lowPriority:(BOOL)lowPriority;
以上三个SDWebImageManager类中的三个方法,功能是根据URL加载对应的图片数据,内部实现的思路:
1、先通过SDImageCache到缓存中获取,看是否有缓存数据
2、如果缓存中无图片数据,则使用SDWebImageDownloader进行网络下载图片
3、下载图片完成之后,再调用SDImageCache将图片数据存入缓存
五、UIImageView+WebCache
- (void)setImageWithURL:(NSURL *)url;
此方法中的内部实现,调用SDWebImageManager加载url对应的图片数据,加载完成之后,给UIImageView显示
其他功能
****UIImage+GIF****
用于解析GIF图片,进行GIF播放使用
****SDWebImageDecoder.h****
解码图片,获取解码之后的UIImage,从缓存、网络中获取的图片,都是先调用这个类进行解码之后的图片。优化性能