每次读优秀的代码都是一次深入的学习,每一次模仿,都是创造的开始!web
——QQ 316045346 欢迎交流缓存
SDWebImage是iOS开发中很是流行的一个网络图片加载库,若是你观察其源码,会发现其中的文件很是多,虽然文件数不少,可是做者的代码结构和条理倒是非清晰。SDWebImage的代码结构基本能够分为3块:应用层类别、核心功能类、工具类与类别。其中咱们最常使用的是应用层的类别。例如UIImageView的图片加载,UIButton的图片加载等。cookie
这个类别是一个图片数据的格式帮助类,使用它能够方便的获取图片数据的图片格式,其中枚举了经常使用的图片格式以下:网络
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;
这个类是SDWebImage中封装的图像帧类,主要用来建立动画图像。函数
//当前帧图像 @property (nonatomic, strong, readonly, nonnull) UIImage *image; //时间 @property (nonatomic, readonly, assign) NSTimeInterval duration; //初始化方法 + (instancetype _Nonnull)frameWithImage:(UIImage * _Nonnull)image duration:(NSTimeInterval)duration;
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;
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的核心功能类结构以下图所示:fetch
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;
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;
这个类别用来对按钮设置网络图片。
//当前状态的图片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;
这两个类别的做用都是对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 };