SDWebImage源碼分析

SDWebImage源碼分析 

    每次讀優秀的代碼都是一次深入的學習,每一次模仿,都是創造的開始!web

——QQ 316045346 歡迎交流緩存

     SDWebImage是iOS開發中很是流行的一個網絡圖片加載庫,若是你觀察其源碼,會發現其中的文件很是多,雖然文件數不少,可是做者的代碼結構和條理倒是非清晰。SDWebImage的代碼結構基本能夠分爲3塊:應用層類別、核心功能類、工具類與類別。其中咱們最常使用的是應用層的類別。例如UIImageView的圖片加載,UIButton的圖片加載等。cookie

1、幫助類與類別的解析

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;

二、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;

2、核心功能

    SDWebImage的核心功能類結構以下圖所示:fetch

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;

3、應用類別

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
};
相關文章
相關標籤/搜索