SD一點(diǎn)小體會

匯總記錄:

本文基于SDWebImage 4.2.3版本進(jìn)行分析和整理。

SDWebImage

|----SDWebImageCompat處理不同平臺(iOS、TV、OS、Watch)宏,以及根據(jù)文件名@2x、@3x進(jìn)行圖片處理和縮放

|----SDWebImageOperation.h添加cancel的delegate

+----Cache

|--------SDImageCache主要處理緩存邏輯,重點(diǎn)集中在:NSCache(Memory)、Disk讀寫、清理Old File

|--------SDImageCacheConfig配置緩存參數(shù):是否壓縮、iCloud、InMemory、ReadingOption、時間和CacheSize

+----Downloader

|--------SDWebImageDownloaderOperation主要提供下載的Operation操作

|--------SDWebImageDownloader提供下載管理入口

+----Utils

|--------SDWebImageManager提供外層管理cache和download入口

|--------SDWebImagePrefetcher預(yù)處理獲取Image,主要應(yīng)用預(yù)加載的地方

+----Categories

|--------NSData+ImageContentType提供類型判斷和ImageIO類型轉(zhuǎn)換

|--------UIImage+GIFData轉(zhuǎn)UIImage(GIF)擴(kuò)展

|--------UIImage+MultiFormat提供BitMap或者未知類型的Data轉(zhuǎn)UIImage擴(kuò)展

|--------UIImage+WebPData轉(zhuǎn)WebP擴(kuò)展

|--------UIImage+ForceDecode解壓操作

|--------UIView+WebCacheOperation提供頂層關(guān)于取消和下載記錄的擴(kuò)展

+----Decoder

|--------SDWebImageCodersManager整體Coders的入口,提供是否可Coder和Coder轉(zhuǎn)發(fā)

|--------SDWebImageCoder主要說明Coder Delegate 需要實(shí)現(xiàn)的接口

|--------SDWebImageImageIOCoderPNG/JPEG的Encode和解壓操作

|--------SDWebImageGIFCoderGIF的Coder操作

|--------SDWebImageWebPCoderWebP的Coder操作

|--------SDWebImageFrame輔助類,主要在GIF等動態(tài)圖使用

|--------SDWebImageCoderHelper輔助類,包括方向、Gif圖合成等

整體組件結(jié)構(gòu)


sd結(jié)構(gòu)

整體框架結(jié)構(gòu)比較清晰,因為Decoder部分相對比較獨(dú)立,業(yè)務(wù)邏輯處理主要在Cache、Downloader層級以及以上。

下文會以Cache、Downloader進(jìn)行分解。


1、緩存部分解析

緩存部分邏輯主要是在SDImageCache,包括如下幾個方面:

新增

刪除

查詢

緩存管理(過期)

SDWebImage的緩存中,主要走了一套NSCache管理內(nèi)存和根據(jù)傳入的Key轉(zhuǎn)換MD5作為文件名存儲。以及創(chuàng)建了一個IO操作的Queue進(jìn)行管理IO操作。

這里重點(diǎn)注意,任何耗時:包括IO讀寫、轉(zhuǎn)碼等操作,都不應(yīng)該放到主線程里面使用。

緩存部分其他地方都比較簡單易懂,直接看源碼即可。

重點(diǎn)說下如下兩個值得學(xué)習(xí)的地方:

1、通過NSOperation管理queue任務(wù)

- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key done:(nullable SDCacheQueryCompletedBlock)doneBlock {

? ? if (!key) {

? ? ? ? if (doneBlock) {

? ? ? ? ? ? doneBlock(nil, nil, SDImageCacheTypeNone);

? ? ? ? }

? ? ? ? return nil;

? ? }

? ? // First check the in-memory cache...

? ? UIImage *image = [self imageFromMemoryCacheForKey:key];

? ? if (image) {

? ? ? ? NSData *diskData = nil;

? ? ? ? if (image.images) {

? ? ? ? ? ? diskData = [self diskImageDataBySearchingAllPathsForKey:key];

? ? ? ? }

? ? ? ? if (doneBlock) {

? ? ? ? ? ? doneBlock(image, diskData, SDImageCacheTypeMemory);

? ? ? ? }

? ? ? ? return nil;

? ? }

? ? NSOperation *operation = [NSOperation new];

? ? dispatch_async(self.ioQueue, ^{

? ? ? ? if (operation.isCancelled) {

? ? ? ? ? ? // do not call the completion if cancelled

? ? ? ? ? ? return;

? ? ? ? }

? ? ? ? @autoreleasepool {

? ? ? ? ? ? NSData *diskData = [self diskImageDataBySearchingAllPathsForKey:key];

? ? ? ? ? ? UIImage *diskImage = [self diskImageForKey:key];

? ? ? ? ? ? if (diskImage && self.config.shouldCacheImagesInMemory) {

? ? ? ? ? ? ? ? NSUInteger cost = SDCacheCostForImage(diskImage);

? ? ? ? ? ? ? ? [self.memCache setObject:diskImage forKey:key cost:cost];

? ? ? ? ? ? }

? ? ? ? ? ? if (doneBlock) {

? ? ? ? ? ? ? ? dispatch_async(dispatch_get_main_queue(), ^{

? ? ? ? ? ? ? ? ? ? doneBlock(diskImage, diskData, SDImageCacheTypeDisk);

? ? ? ? ? ? ? ? });

? ? ? ? ? ? }

? ? ? ? }

? ? });

? ? return operation;

}

查詢緩存的時候,這里采用了NSOperation進(jìn)行是否取消的操作,因為當(dāng)下載/緩存內(nèi)容過多時,畢定存在先后處理順序的問題,這時候可能由于用戶操作等需要取消當(dāng)前緩存處理,那么NSOperation這里起的唯一作用就是提供取消操作??梢詤⒖季唧w的Manager里面緩存調(diào)起邏輯

2、申請系統(tǒng)后臺時間處理任務(wù)

-(void)backgroundDeleteOldFiles{Class UIApplicationClass=NSClassFromString(@"UIApplication");if(!UIApplicationClass||![UIApplicationClass respondsToSelector:@selector(sharedApplication)]){return;}UIApplication*application=[UIApplication performSelector:@selector(sharedApplication)];__block UIBackgroundTaskIdentifier bgTask=[application beginBackgroundTaskWithExpirationHandler:^{// Clean up any unfinished task business by marking where you// stopped or ending the task outright.[application endBackgroundTask:bgTask];bgTask=UIBackgroundTaskInvalid;}];// Start the long-running task and return immediately.[selfdeleteOldFilesWithCompletionBlock:^{[application endBackgroundTask:bgTask];bgTask=UIBackgroundTaskInvalid;}];}

這里有個疑問點(diǎn)要注意,為啥會存在前后兩部分都去釋放Task任務(wù)。

iOS的后臺任務(wù)有個背景,不管任何時候,都需要手動去調(diào)用endBackgroundTask結(jié)束后臺任務(wù),其實(shí)開啟一個后臺job的時候,因為時長有限,所以會存在兩種結(jié)局:

在允許的時間內(nèi)執(zhí)行完成

規(guī)定時間內(nèi)未執(zhí)行完成

如上兩種情況,在結(jié)束后都必須手動調(diào)用endBackgroundTask:

2、下載器(Downloader)

下載部分,主要是提供了一個Operation和一個Manager,其中SDWebImageDownloaderOperation里面提供了常用的Operation操作,也支持自定義的下載邏輯(實(shí)現(xiàn)SDWebImageDownloaderOperationInterface即可)。

2.1 SDWebImageDownloaderOperation 邏輯

該文件里面重點(diǎn)是Delegate:SDWebImageDownloaderOperationInterface的設(shè)計和一種實(shí)現(xiàn)方式SDWebImageDownloaderOperation(PS:優(yōu)秀的開源庫基本都會設(shè)計一套接口,再做一套基礎(chǔ)的實(shí)現(xiàn))。

// 這里描述寫的很清楚,如果需要自定義的Downloader op,那么需要繼承NSOperation并且實(shí)現(xiàn)SDWebImageDownloaderOperation

/**

Describes a downloader operation. If one wants to use a custom downloader op, it needs to inherit from `NSOperation` and conform to this protocol

*/

@protocol SDWebImageDownloaderOperationInterface<NSObject>

- (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? inSession:(nullable NSURLSession *)session

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? options:(SDWebImageDownloaderOptions)options;

- (nullable id)addHandlersForProgress:(nullable SDWebImageDownloaderProgressBlock)progressBlock

? ? ? ? ? ? ? ? ? ? ? ? ? ? completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock;

- (BOOL)shouldDecompressImages;

- (void)setShouldDecompressImages:(BOOL)value;

- (nullable NSURLCredential *)credential;

- (void)setCredential:(nullable NSURLCredential *)value;

@end

SDWebImageDownloaderOperation主要是提供內(nèi)置的下載實(shí)現(xiàn),重點(diǎn)是使用NSURLSessionTask進(jìn)行下載,邏輯不復(fù)雜,詳細(xì)的參考源碼

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容