SDWebImage源码分析

简介: SDWebImage源码分析

SDWebImage是iOS开发中非常流行的一个网络图片加载库,如果你观察其源码,会发现其中的文件非常多,虽然文件数很多,但是作者的代码结构和条理却是非清晰。SDWebImage的代码结构基本可以分为3块:应用层类别、核心功能类、工具类与类别。其中我们最常使用的是应用层的类别。例如UIImageView的图片加载,UIButton的图片加载等。


一、帮助类与类别的解析


1.NSData+ImageContentType


   这个类别是一个图片数据的格式帮助类,使用它可以方便的获取图片数据的图片格式,其中枚举了常用的图片格式如下:


typedef NS_ENUM(NSInteger, SDImageFormat) {

   SDImageFormatUndefined = -1, //未知格式

   SDImageFormatJPEG = 0,   //jpeg

   SDImageFormatPNG,   //png

   SDImageFormatGIF,   //gif

   SDImageFormatTIFF,  //tiff

   SDImageFormatWebP,  //webp

   SDImageFormatHEIC   //heic

};

其原理是根据图片数据的第1个字节码进行分析,不同格式的图像数据在开头都会有一部分的用来表明图像信息的数据块,通过它可以获取图片的具体格式。这个类别中只提供了两个方法:


//获取图像数据格式

+ (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data;

//将SDImageFormat转换成CFStringRef

+ (nonnull CFStringRef)sd_UTTypeFromSDImageFormat:(SDImageFormat)format;

2、SDWebImageFrame


   这个类是SDWebImage中封装的图像帧类,主要用来创建动画图像。


//当前帧图像

@property (nonatomic, strong, readonly, nonnull) UIImage *image;

//时间

@property (nonatomic, readonly, assign) NSTimeInterval duration;

//初始化方法

+ (instancetype _Nonnull)frameWithImage:(UIImage * _Nonnull)image duration:(NSTimeInterval)duration;

3.UIImage的编码与解码


   SDWebImageCoder中定义了一个协议,其中约定了方法来对图像数据进行解码与编码,实现这个协议的主要有SDWebImageIOCoder和SDWebImageGIFCoder。


//数据是否可以进行解码 除了webp类型的 其他类型的图像都可以解码

- (BOOL)canDecodeFromData:(nullable NSData *)data;

//进行图片数据解码

- (nullable UIImage *)decodedImageWithData:(nullable NSData *)data;

//进行增量解码

- (nullable UIImage *)decompressedImageWithImage:(nullable UIImage *)image

                                           data:(NSData * _Nullable * _Nonnull)data

                                        options:(nullable NSDictionary<NSString*, NSObject*>*)optionsDict;

//获取此类型图像是否可以编码

- (BOOL)canEncodeToFormat:(SDImageFormat)format;

//将图片编码为数据

- (nullable NSData *)encodedDataWithImage:(nullable UIImage *)image format:(SDImageFormat)format;

//获取此图像数据是否可以增量解码

- (BOOL)canIncrementallyDecodeFromData:(nullable NSData *)data;

//进行增量解码

- (nullable UIImage *)incrementallyDecodedImageWithData:(nullable NSData *)data finished:(BOOL)finished;

4.图像数据预加载


   SDWebImagePrefetcher类提供了图像数据的预加载功能,在进行用户体验优化,需要预加载某些常态图像时,可以用使用这个类。


@interface SDWebImagePrefetcher : NSObject

//管理中心

@property (strong, nonatomic, readonly, nonnull) SDWebImageManager *manager;

//设置最大的同时下载数

@property (nonatomic, assign) NSUInteger maxConcurrentDownloads;

//配置 枚举 设置优先级等

@property (nonatomic, assign) SDWebImageOptions options;

//单例对象

+ (nonnull instancetype)sharedImagePrefetcher;

//构造方法

- (nonnull instancetype)initWithImageManager:(nonnull SDWebImageManager *)manager NS_DESIGNATED_INITIALIZER;

//进行预下载

- (void)prefetchURLs:(nullable NSArray<NSURL *> *)urls;

- (void)prefetchURLs:(nullable NSArray<NSURL *> *)urls

           progress:(nullable SDWebImagePrefetcherProgressBlock)progressBlock

          completed:(nullable SDWebImagePrefetcherCompletionBlock)completionBlock;

//取消预下载行为

- (void)cancelPrefetching;

SDWebImagePrefetcher还提供了代理来对预下载过程进行监听,如下:


//当一张图片被下载完后调用

- (void)imagePrefetcher:(nonnull SDWebImagePrefetcher *)imagePrefetcher didPrefetchURL:(nullable NSURL *)imageURL finishedCount:(NSUInteger)finishedCount totalCount:(NSUInteger)totalCount;

//与下载任务全部结束后调用

- (void)imagePrefetcher:(nonnull SDWebImagePrefetcher *)imagePrefetcher didFinishWithTotalCount:(NSUInteger)totalCount skippedCount:(NSUInteger)skippedCount;

二、核心功能


   SDWebImage的核心功能类结构如下图所示:


image.png


1.缓存管理类SDImageCache


   SDImageCache类负责所有网络图片数据的缓存,其从逻辑上分为两级缓存,内存缓存和硬盘缓存。开发者可以使用单例方法来获取默认的SDImageCache实例,也可以使用特殊的Name值来创建缓存实例,常用函数列举如下:


//缓存图片到内存和磁盘

- (void)storeImage:(nullable UIImage *)image

           forKey:(nullable NSString *)key

       completion:(nullable SDWebImageNoParamsBlock)completionBlock;

//缓存图片到磁盘

- (void)storeImage:(nullable UIImage *)image

           forKey:(nullable NSString *)key

           toDisk:(BOOL)toDisk

       completion:(nullable SDWebImageNoParamsBlock)completionBlock;

- (void)storeImage:(nullable UIImage *)image

        imageData:(nullable NSData *)imageData

           forKey:(nullable NSString *)key

           toDisk:(BOOL)toDisk

       completion:(nullable SDWebImageNoParamsBlock)completionBlock;

- (void)storeImageDataToDisk:(nullable NSData *)imageData forKey:(nullable NSString *)key;

//异步检查磁盘缓存是否存在

- (void)diskImageExistsWithKey:(nullable NSString *)key completion:(nullable SDWebImageCheckCacheCompletionBlock)completionBlock;

//检查内存缓存是否存在

- (nullable UIImage *)imageFromMemoryCacheForKey:(nullable NSString *)key;

//获取磁盘缓存数据

- (nullable UIImage *)imageFromDiskCacheForKey:(nullable NSString *)key;

//获取内存和磁盘缓存数据

- (nullable UIImage *)imageFromCacheForKey:(nullable NSString *)key;

//异步删除缓存

- (void)removeImageForKey:(nullable NSString *)key withCompletion:(nullable SDWebImageNoParamsBlock)completion;

- (void)removeImageForKey:(nullable NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(nullable SDWebImageNoParamsBlock)completion;

//清除所有内存缓存

- (void)clearMemory;

//删除所有过期数据

- (void)deleteOldFilesWithCompletionBlock:(nullable SDWebImageNoParamsBlock)completionBlock;

//获取磁盘缓存大小

- (NSUInteger)getSize;

//获取磁盘缓存图片数

- (NSUInteger)getDiskCount;

SDImageCacheConfig用来对缓存进行配置,如下:


//是否允许缓存到内存

@property (assign, nonatomic) BOOL shouldCacheImagesInMemory;

//缓存生命

@property (assign, nonatomic) NSInteger maxCacheAge;

//最大缓存容量

@property (assign, nonatomic) NSUInteger maxCacheSize;

2.下载器SDWebImageDownloader


   SDWebImageDownloader提供对图片下载的支持管理,其可以配置同时最大下载数量,下载超时等:


//同时最大下载数量

@property (assign, nonatomic) NSInteger maxConcurrentDownloads;

//当前正在下载的任务数量

@property (readonly, nonatomic) NSUInteger currentDownloadCount;

//设置超时时间

@property (assign, nonatomic) NSTimeInterval downloadTimeout;

//证书

@property (strong, nonatomic, nullable) NSURLCredential *urlCredential;

//用户名

@property (strong, nonatomic, nullable) NSString *username;

//密码

@property (strong, nonatomic, nullable) NSString *password;

//设置请求头

- (void)setValue:(nullable NSString *)value forHTTPHeaderField:(nullable NSString *)field;

//获取请求头

- (nullable NSString *)valueForHTTPHeaderField:(nullable NSString *)field;

//开始下载任务

- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url

                                                  options:(SDWebImageDownloaderOptions)options

                                                 progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock

                                                completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock;

//取消下载任务

- (void)cancel:(nullable SDWebImageDownloadToken *)token;

//取消所有下载任务

- (void)cancelAllDownloads;

三、应用类别


1.UIButton+WebCache


   这个类别用来对按钮设置网络图片。


//当前状态的图片URL

- (nullable NSURL *)sd_currentImageURL;

//获取指定状态的图片URL

- (nullable NSURL *)sd_imageURLForState:(UIControlState)state;

//为某个状态设置网络图片

- (void)sd_setImageWithURL:(nullable NSURL *)url

                 forState:(UIControlState)state;

- (void)sd_setImageWithURL:(nullable NSURL *)url

                 forState:(UIControlState)state

         placeholderImage:(nullable UIImage *)placeholder;

- (void)sd_setImageWithURL:(nullable NSURL *)url

                 forState:(UIControlState)state

         placeholderImage:(nullable UIImage *)placeholder

                  options:(SDWebImageOptions)options;

- (void)sd_setImageWithURL:(nullable NSURL *)url

                 forState:(UIControlState)state

                completed:(nullable SDExternalCompletionBlock)completedBlock;

- (void)sd_setImageWithURL:(nullable NSURL *)url

                 forState:(UIControlState)state

         placeholderImage:(nullable UIImage *)placeholder

                completed:(nullable SDExternalCompletionBlock)completedBlock;

- (void)sd_setImageWithURL:(nullable NSURL *)url

                 forState:(UIControlState)state

         placeholderImage:(nullable UIImage *)placeholder

                  options:(SDWebImageOptions)options

                completed:(nullable SDExternalCompletionBlock)completedBlock;

//下面这些方法设置按钮的背景图

- (nullable NSURL *)sd_currentBackgroundImageURL;

- (nullable NSURL *)sd_backgroundImageURLForState:(UIControlState)state;

- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url

                           forState:(UIControlState)state;

- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url

                           forState:(UIControlState)state

                   placeholderImage:(nullable UIImage *)placeholder;

- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url

                           forState:(UIControlState)state

                   placeholderImage:(nullable UIImage *)placeholder

                            options:(SDWebImageOptions)options;

- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url

                           forState:(UIControlState)state

                          completed:(nullable SDExternalCompletionBlock)completedBlock;

- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url

                           forState:(UIControlState)state

                   placeholderImage:(nullable UIImage *)placeholder

                          completed:(nullable SDExternalCompletionBlock)completedBlock;

- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url

                           forState:(UIControlState)state

                   placeholderImage:(nullable UIImage *)placeholder

                            options:(SDWebImageOptions)options

                          completed:(nullable SDExternalCompletionBlock)completedBlock;

//取消图片下载

- (void)sd_cancelImageLoadForState:(UIControlState)state;

- (void)sd_cancelBackgroundImageLoadForState:(UIControlState)state;

2.UIImageView+WebCache与UIImageView+HighlightedWebCache


   这两个类别的作用都是对UIImageView实例进行图片设置,分别设置正常状态的图片和高亮状态的图片。只举例UIImageView+WebCache中方法如下:


//设置网络图片

- (void)sd_setImageWithURL:(nullable NSURL *)url;

- (void)sd_setImageWithURL:(nullable NSURL *)url

         placeholderImage:(nullable UIImage *)placeholder;

- (void)sd_setImageWithURL:(nullable NSURL *)url

         placeholderImage:(nullable UIImage *)placeholder

                  options:(SDWebImageOptions)options;

- (void)sd_setImageWithURL:(nullable NSURL *)url

                completed:(nullable SDExternalCompletionBlock)completedBlock;

- (void)sd_setImageWithURL:(nullable NSURL *)url

         placeholderImage:(nullable UIImage *)placeholder

                completed:(nullable SDExternalCompletionBlock)completedBlock;

- (void)sd_setImageWithURL:(nullable NSURL *)url

         placeholderImage:(nullable UIImage *)placeholder

                  options:(SDWebImageOptions)options

                completed:(nullable SDExternalCompletionBlock)completedBlock;

- (void)sd_setImageWithURL:(nullable NSURL *)url

         placeholderImage:(nullable UIImage *)placeholder

                  options:(SDWebImageOptions)options

                 progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock

                completed:(nullable SDExternalCompletionBlock)completedBlock;

- (void)sd_setImageWithPreviousCachedImageWithURL:(nullable NSURL *)url

                                placeholderImage:(nullable UIImage *)placeholder

                                         options:(SDWebImageOptions)options

                                        progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock

                                       completed:(nullable SDExternalCompletionBlock)completedBlock;

//对一组url进行下载并以动画方式显示

- (void)sd_setAnimationImagesWithURLs:(nonnull NSArray<NSURL *> *)arrayOfURLs;

//取消当前图片下载

- (void)sd_cancelCurrentAnimationImagesLoad;

关于SDWebImageOptions,它是一个配置枚举:


typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) {

   //配置这个参数下载失败的url将会重试下载

   SDWebImageRetryFailed = 1 << 0,

   //低优先级

   SDWebImageLowPriority = 1 << 1,

   //仅仅进行内存缓存

   SDWebImageCacheMemoryOnly = 1 << 2,

   //进行分步下载

   SDWebImageProgressiveDownload = 1 << 3,

   //刷新缓存

   SDWebImageRefreshCached = 1 << 4,

   //支持后台

   SDWebImageContinueInBackground = 1 << 5,

   //保持cookie

   SDWebImageHandleCookies = 1 << 6,

   //允许证书

   SDWebImageAllowInvalidSSLCertificates = 1 << 7,

   //高优先级

   SDWebImageHighPriority = 1 << 8,

   //配置此参数 当图片加载结束后才会显示placeholder

   SDWebImageDelayPlaceholder = 1 << 9,

   //执行图片变换

   SDWebImageTransformAnimatedImage = 1 << 10,

   SDWebImageScaleDownLargeImages = 1 << 12

};

 

目录
相关文章
Volley源码分析(一)
Volley源码分析(一)
191 0
|
缓存 数据安全/隐私保护
SDWebImage的应用(常用)
SDWebImage的应用(常用)
270 0
SDWebImage的应用(常用)
|
编译器 iOS开发
iOS-底层原理 23:KVO 底层原理
iOS-底层原理 23:KVO 底层原理
220 0
iOS-底层原理 23:KVO 底层原理
|
iOS开发
iOS-底层原理 04:NSObject的alloc 源码分析
iOS-底层原理 04:NSObject的alloc 源码分析
141 0
iOS-底层原理 04:NSObject的alloc 源码分析
|
安全 iOS开发
iOS探索 -- KVO 的原理分析
KVO (key-value-observing) 是一种 键值观察 机制, 它允许当前对象去观察目标对象的某个属性的变化; 当被观察对象的属性发生变化后, 会通过特定方法通知观察者对象属性变化的一些情况内容, 观察者对象拿到变化情况后做出相关操作。
196 0
|
安全 开发者
MJRefresh源码分析
MJRefresh源码分析
186 0
MJRefresh源码分析
|
存储 缓存 编解码
如何实现一个图片加载框架
一、前言 图片加载的轮子有很多了,Universal-Image-Loader, Picasso, Glide, Fresco等。网上各种分析和对比文章很多,我们这里就不多作介绍了。 古人云:“纸上得来终觉浅,绝知此事要躬行”。
2311 0
|
缓存
SDWebImage探究
SDWebImage探究(一)SDWebImage探究(二)SDWebImage探究(三)SDWebImage探究(四)SDWebImage探究(五)SDWebImage探究(六) —— 图片类型判断深入研究SDWebImage探究(七) —— 深入研...
1062 0
|
存储 安全 Java
关于glide图片加载框架的实际使用要点
第一部分:先说用glide踩的坑。 最近在项目中,加载图片用的是glide框架,遇到坑的地方,在load(url),内的url不能丢了。比如: Glide.with(mContext)         .load("img2.3lian.com/2014/f6/173/d/55.jpg")         .into(ivOrderGoodsImg); 这样,图片无法显示,一般glide载入图片失败有几个原因,1:into()方法没有载入正确的ImageView控件,比如载入到TextView的实例化对象中;2:load()方法中的网址不正确。
1710 0