圖解AFNetworking中提供的圖片緩存類

AFAutoPurgingImageCache:自動清理的圖片緩存類

一冗酿、整體的結構:

綠色公有画拾、黃色私有

二熟菲、重要屬性:

  • 公有的:
    memoryCapacity:緩存最大在內存中占據的大小朋贬,默認100M
    preferredMemoryUsageAfterPurge:進行緩存清理時期望剩余緩存圖片占據的大小椭更,默認60M
    memoryUsage:以緩存的圖片占據的大小

  • 私有的:
    cachedImages:圖片所在的集合
    currentMemoryUsage:記錄當前緩存圖片占據的大小,公有屬性memoryUsage就是讀取它的值
    synchronizationQueue:并行隊列饶深,對cachedImages讀婿滓、寫任務由該隊列調度

三、主要方法

3.1存數(shù)據的方法
- (void)addImage:(UIImage *)image withIdentifier:(NSString *)identifier {
     // #1:異步任務向字典集合中添加圖片
    dispatch_barrier_async(self.synchronizationQueue, ^{
        AFCachedImage *cacheImage = [[AFCachedImage alloc] initWithImage:image identifier:identifier];
        AFCachedImage *previousCachedImage = self.cachedImages[identifier];
        if (previousCachedImage != nil) {//如果有同一標識的AFCachedImage存在就先減去它的大小
            self.currentMemoryUsage -= previousCachedImage.totalBytes;
        }
        self.cachedImages[identifier] = cacheImage;
        self.currentMemoryUsage += cacheImage.totalBytes;//把新添加的圖片大小計算在內
    });
    // #2:異步任務粥喜,若#1操作后緩存總大小大于預先設定的大小,這時間順序清楚部分緩存直到preferredMemoryUsageAfterPurge設置的大小
    dispatch_barrier_async(self.synchronizationQueue, ^{
        if (self.currentMemoryUsage > self.memoryCapacity) {
            UInt64 bytesToPurge = self.currentMemoryUsage - self.preferredMemoryUsageAfterPurge;
            NSMutableArray <AFCachedImage*> *sortedImages = [NSMutableArray arrayWithArray:self.cachedImages.allValues];
            NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastAccessDate"                                                                           ascending:YES];
            [sortedImages sortUsingDescriptors:@[sortDescriptor]];
            UInt64 bytesPurged = 0;
            for (AFCachedImage *cachedImage in sortedImages) {
                [self.cachedImages removeObjectForKey:cachedImage.identifier];
                bytesPurged += cachedImage.totalBytes;
                if (bytesPurged >= bytesToPurge) {
                    break ;
                }
            }
            self.currentMemoryUsage -= bytesPurged;
        }
    });
}

這個方法中兩次用到dispatch_barrier_async()向并行隊列中添加異步任務橘券,這兩個任務會等待隊列中的其他任務執(zhí)行完畢后再開始執(zhí)行额湘,就像一道“墻”一樣保證了同一時刻只有一個線程執(zhí)行寫操作

3.2清除數(shù)據數(shù)據的方法
- (BOOL)removeImageWithIdentifier:(NSString *)identifier {
    __block BOOL removed = NO;
    dispatch_barrier_sync(self.synchronizationQueue, ^{
        AFCachedImage *cachedImage = self.cachedImages[identifier];
        if (cachedImage != nil) {
            [self.cachedImages removeObjectForKey:identifier];
            self.currentMemoryUsage -= cachedImage.totalBytes;
            removed = YES;
        }
    });
    return removed;
}
- (BOOL)removeAllImages {...}

清除數(shù)據也是一種寫操作,所有要用barrier旁舰;又因為要以返回值的形式向外傳遞處理結果锋华,所以要用sync同步操作。

3.3獲取數(shù)據的方法
- (nullable UIImage *)imageWithIdentifier:(NSString *)identifier {
    __block UIImage *image = nil;
    dispatch_sync(self.synchronizationQueue, ^{
        AFCachedImage *cachedImage = self.cachedImages[identifier];
        image = [cachedImage accessImage];
    });
    return image;
}

同步獲取數(shù)據是一種讀操作箭窜,多個任務可以同時進行毯焕。如下圖:

異步的寫法:

- (void)imageWithIdentifier:(NSString *)identifier completion:(void (^)(UIImage *))handler {
    __block UIImage *image = nil;
    dispatch_async(self.synchronizationQueue, ^{
        AFCachedImage *cachedImage = self.cachedImages[identifier];
        image = [cachedImage accessImage];
        dispatch_async(dispatch_get_main_queue(), ^{
            if (handler) {
                handler(image);
            }
        });
    });
}

總結

這個類相對簡單而且可以單獨使用,從中可以學習到處理非線程安全的對象(這里是NSMutableDictionary)時的一些方法磺樱。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末纳猫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子竹捉,更是在濱河造成了極大的恐慌芜辕,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件块差,死亡現(xiàn)場離奇詭異侵续,居然都是意外死亡,警方通過查閱死者的電腦和手機憨闰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門状蜗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鹉动,你說我怎么就攤上這事轧坎。” “怎么了训裆?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵眶根,是天一觀的道長蜀铲。 經常有香客問我,道長属百,這世上最難降的妖魔是什么记劝? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮族扰,結果婚禮上厌丑,老公的妹妹穿的比我還像新娘。我一直安慰自己渔呵,他們只是感情好怒竿,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著扩氢,像睡著了一般耕驰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上录豺,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天朦肘,我揣著相機與錄音,去河邊找鬼双饥。 笑死媒抠,一個胖子當著我的面吹牛,可吹牛的內容都是我干的咏花。 我是一名探鬼主播趴生,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼昏翰!你這毒婦竟也來了苍匆?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤矩父,失蹤者是張志新(化名)和其女友劉穎锉桑,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體窍株,經...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡民轴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了球订。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片后裸。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖冒滩,靈堂內的尸體忽然破棺而出微驶,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布因苹,位于F島的核電站苟耻,受9級特大地震影響,放射性物質發(fā)生泄漏扶檐。R本人自食惡果不足惜凶杖,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望款筑。 院中可真熱鬧智蝠,春花似錦、人聲如沸奈梳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽攘须。三九已至漆撞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間于宙,已是汗流浹背叫挟。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留限煞,地道東北人。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓员凝,卻偏偏與公主長得像署驻,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子健霹,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內容