SDWebImage源代碼解析(四)Categories

前言

CSDN地址:http://blog.csdn.net/game3108/article/details/52700626
本文的中文注釋代碼demo更新在我的github上。

上篇文章講解的了SDWebImage的Utils部分楔壤,這篇講講一下最后的Categories部分饶碘。

Categories

Categories包含以下幾個類文件:

  • MKAnnotationView+WebCache
  • NSData+ImageContentType
  • UIButton+WebCache
  • UIImage+GIF
  • UIImage+MultiFormat
  • UIImage+WebP
  • UIImageView+HighlightedWebCache
  • UIImageView+WebCache
  • UIView+WebCacheOperation

這邊只介紹一下UIView+WebCacheOperationUIImageView+WebCache,其他文件類似殖侵,這里也不多展開了,在github的注釋里會盡量都看一遍。

UIView+WebCacheOperation

UIView+WebCacheOperation主要通過associateObject的方式和屎,去緩存和取消、刪除運行的操作春瞬。
相關(guān)方法定義如下:

/**
 設(shè)置圖片的load操作(存入一個uiview的字典)

 @param operation 操作
 @param key       存入的key
 */
- (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key;

/**
 取消當前uiview的key的操作

 @param key 存入的key
 */
- (void)sd_cancelImageLoadOperationWithKey:(NSString *)key;

/**
 移除當前uiview的key的操作柴信,并且不取消他們

 @param key 存入的key
 */
- (void)sd_removeImageLoadOperationWithKey:(NSString *)key;

相關(guān)實現(xiàn):

static char loadOperationKey;

- (NSMutableDictionary *)operationDictionary {
    //通過associateobject去存入和獲取dictionaryu
    NSMutableDictionary *operations = objc_getAssociatedObject(self, &loadOperationKey);
    if (operations) {
        return operations;
    }
    operations = [NSMutableDictionary dictionary];
    objc_setAssociatedObject(self, &loadOperationKey, operations, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    return operations;
}

- (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key {
    //先取消操作
    [self sd_cancelImageLoadOperationWithKey:key];
    //然后獲取dictionary并存入
    NSMutableDictionary *operationDictionary = [self operationDictionary];
    [operationDictionary setObject:operation forKey:key];
}

- (void)sd_cancelImageLoadOperationWithKey:(NSString *)key {
    // Cancel in progress downloader from queue
    //獲取dictionary,并且取消在queue中的操作
    NSMutableDictionary *operationDictionary = [self operationDictionary];
    id operations = [operationDictionary objectForKey:key];
    if (operations) {
        //數(shù)組的話獲取內(nèi)部所有的取消
        if ([operations isKindOfClass:[NSArray class]]) {
            for (id <SDWebImageOperation> operation in operations) {
                if (operation) {
                    [operation cancel];
                }
            }
            //如果是實現(xiàn)SDWebImageOperation契約宽气,直接取消
        } else if ([operations conformsToProtocol:@protocol(SDWebImageOperation)]){
            [(id<SDWebImageOperation>) operations cancel];
        }
        [operationDictionary removeObjectForKey:key];
    }
}

- (void)sd_removeImageLoadOperationWithKey:(NSString *)key {
    //獲取dictionary并直接刪除key
    NSMutableDictionary *operationDictionary = [self operationDictionary];
    [operationDictionary removeObjectForKey:key];
}

UIImageView+WebCache

UIImageView+WebCache就是UIImage用到的sdwebimage的category随常,用戶最外層的調(diào)用方式。
這邊貼其中最基礎(chǔ)的操作方法的定義和實現(xiàn):

/**
 通過url萄涯,設(shè)置imageview的image绪氛,placeholder和設(shè)置
 
 下載方式異步并且緩存
 
 @param url            圖片url
 @param placeholder    初始化圖片
 @param options        下載圖片方式
 @param progressBlock  進度block回調(diào)
 @param completedBlock 完成block回調(diào)
 */
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
    //取消當前的圖片下載
    [self sd_cancelCurrentImageLoad];
    //保存url
    objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    //如果沒有SDWebImageDelayPlaceholder則先設(shè)置placeholder圖
    if (!(options & SDWebImageDelayPlaceholder)) {
        dispatch_main_async_safe(^{
            self.image = placeholder;
        });
    }
    
    //有url進行下載操作
    if (url) {

        // check if activityView is enabled or not
        //是否需要顯示loading標簽圖
        if ([self showActivityIndicatorView]) {
            [self addActivityIndicator];
        }

        //下載圖片
        __weak __typeof(self)wself = self;
        id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
            
            //去掉可能存在的loadting圖
            [wself removeActivityIndicator];
            if (!wself) return;
            dispatch_main_sync_safe(^{
                if (!wself) return;
                
                //不自動設(shè)置圖片
                if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)
                {
                    completedBlock(image, error, cacheType, url);
                    return;
                }
                //設(shè)置圖片
                else if (image) {
                    wself.image = image;
                    [wself setNeedsLayout];
                } else {
                    //沒有圖片設(shè)置默認圖
                    if ((options & SDWebImageDelayPlaceholder)) {
                        wself.image = placeholder;
                        [wself setNeedsLayout];
                    }
                }
                if (completedBlock && finished) {
                    completedBlock(image, error, cacheType, url);
                }
            });
        }];
        //緩存operation的key為load
        [self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"];
    } else {
        //沒有url直接去掉loading圖
        dispatch_main_async_safe(^{
            [self removeActivityIndicator];
            //返回錯誤給外面的block
            if (completedBlock) {
                NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
                completedBlock(nil, error, SDImageCacheTypeNone, url);
            }
        });
    }
}

總結(jié)

到這里,SDWebImage就算全部解析完了窃判。
我個人感覺钞楼,里面比較精髓的是處理圖片的一些細節(jié),比如gif圖片袄琳,還有decode圖片询件,用空間換時間等一些做法,這些細節(jié)的實現(xiàn)是整個圖片處理的基礎(chǔ)唆樊。
在框架上SDWebImage也是進行了多層的封裝宛琅,將最基礎(chǔ)的網(wǎng)絡(luò)操作封裝成operation,再此基礎(chǔ)上再往上封裝一層緩存層逗旁,并用一個manager去進行管理嘿辟。而用戶的使用調(diào)用都在category中實現(xiàn)相應(yīng)的方法舆瘪。

據(jù)說現(xiàn)在正在做4.0版本,會有一些大的變化改動红伦,可以期待一下英古。

參考資料

1.SDWebImage源碼淺析

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市昙读,隨后出現(xiàn)的幾起案子召调,更是在濱河造成了極大的恐慌,老刑警劉巖蛮浑,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件唠叛,死亡現(xiàn)場離奇詭異,居然都是意外死亡沮稚,警方通過查閱死者的電腦和手機艺沼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蕴掏,“玉大人障般,你說我怎么就攤上這事∈⒔埽” “怎么了剩拢?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長饶唤。 經(jīng)常有香客問我,道長贯钩,這世上最難降的妖魔是什么募狂? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮角雷,結(jié)果婚禮上祸穷,老公的妹妹穿的比我還像新娘。我一直安慰自己勺三,他們只是感情好雷滚,可當我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吗坚,像睡著了一般祈远。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上商源,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天车份,我揣著相機與錄音,去河邊找鬼牡彻。 笑死扫沼,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播缎除,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼严就,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了器罐?” 一聲冷哼從身側(cè)響起梢为,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎技矮,沒想到半個月后抖誉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡衰倦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年袒炉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片樊零。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡我磁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出驻襟,到底是詐尸還是另有隱情夺艰,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布沉衣,位于F島的核電站郁副,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏豌习。R本人自食惡果不足惜存谎,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肥隆。 院中可真熱鬧既荚,春花似錦、人聲如沸栋艳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吸占。三九已至晴叨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間矾屯,已是汗流浹背篙螟。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留问拘,地道東北人遍略。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓惧所,卻偏偏與公主長得像,于是被迫代替她去往敵國和親绪杏。 傳聞我的和親對象是個殘疾皇子下愈,可洞房花燭夜當晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 讀完這篇文章你可以自己寫一個 輕量級別的SDWebImage神器,這篇文章類似源碼解析蕾久。但不同的是势似,不僅僅是解析,...
    ZhengYaWei閱讀 3,612評論 10 44
  • 1 概述 SDWebImage基本是iOS項目的標配僧著。他以靈活簡單的api履因,提供了圖片從加載、解析盹愚、處理栅迄、緩存、清...
    NS西北風閱讀 723評論 0 4
  • SDWebImage 一個支持遠程服務(wù)器圖片加載緩存的庫 功能簡介 UIImageView皆怕,UIButton毅舆,MK...
    kwdx閱讀 1,531評論 0 3
  • 在iOS的圖片加載框架中,SDWebImage使用頻率非常高愈腾。它支持從網(wǎng)絡(luò)中下載且緩存圖片憋活,并設(shè)置圖片到對應(yīng)的UI...
    路飛_Luck閱讀 3,101評論 0 15
  • 一、學(xué)習 復(fù)習大筆記(39-43頁)用時76分鐘虱黄。 二悦即、心態(tài) 閱讀能量貝的文章《對一切人、一切事保持絕望橱乱,包括對自...
    風雅狂月閱讀 41評論 0 0