每次讀優秀的代碼都是一次深入的學習,每一次模仿,都是創造的開始!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 };