【iOS】使用NSCache搭建自定義網(wǎng)絡(luò)緩存層

1.為什么要自己搭建緩存機制枢步?

  • 系統(tǒng)的緩存機制把控性低中姜,為了讓自己隨意操作緩存
  • 適應(yīng)特別的業(yè)務(wù)場景,我們可以自定義緩存的生命周期(如:惡意操作脚翘,在控制器之間不斷的push pop反復(fù)請求骂因;時效性低的網(wǎng)絡(luò)數(shù)據(jù))
  • 從框架的角度我們可以解耦對AF的依賴炎咖,(比如替換網(wǎng)絡(luò)請求框架)
  • AF沒有的功能,如多任務(wù)同步異步下載上傳

2.網(wǎng)絡(luò)緩存設(shè)計思路

  • 1.發(fā)起網(wǎng)絡(luò) -> 是否讀取緩存 (是)-> 判斷緩存是否過期(沒過期)——>讀緩存——>返回緩存業(yè)務(wù)數(shù)據(jù)
  • 2.發(fā)起網(wǎng)絡(luò) -> 是否讀取緩存 (是)->判斷緩存是否過期(過期了)——>請求網(wǎng)絡(luò)(AF操作)——>返回AF網(wǎng)絡(luò)數(shù)據(jù)
  • 3 發(fā)起網(wǎng)絡(luò)->是否讀緩存(是否從緩存中拿數(shù)據(jù), 否)——>請求網(wǎng)絡(luò)(AF操作)——>返回AF網(wǎng)絡(luò)數(shù)據(jù)

3.設(shè)計接口時必要的一些參數(shù)

/**
 GET請求
 
 @param urlStr url地址
 @param parameters 請求參數(shù)
 @param ignoreCache 是否忽略緩存寒波,YES 忽略乘盼,NO 不忽略
 @param cacheDuration 緩存時效
 @param completionHandler 請求結(jié)果處理
 */
- (void)taskWithMethod:(NSString*)method
             urlString:(NSString*)urlStr
            parameters:(NSDictionary *)parameters
           ignoreCache:(BOOL)ignoreCache
         cacheDuration:(NSTimeInterval)cacheDuration
     completionHandler:(SYRequestCompletionHandler)completionHandler;

4.架構(gòu)的簡易實現(xiàn)

- (void)taskWithMethod:(NSString*)method
             urlString:(NSString*)urlStr
            parameters:(NSDictionary *)parameters
           ignoreCache:(BOOL)ignoreCache
         cacheDuration:(NSTimeInterval)cacheDuration
     completionHandler:(SYRequestCompletionHandler)completionHandler{
    
    // 1緩存
    // 1.1 urlStr+method+parameters 生成一個唯一標識,個人選用md5的方式
    NSString *fileKeyFromUrl = SYConvertMD5FromParameter(urlStr, method, parameters);
    __weak typeof(self) weakSelf = self;
    
    // 1.2 緩存+失效 判斷是否有有效緩存
    if (!ignoreCache && [self.cache checkIfShouldUseCacheWithCacheDuration:cacheDuration cacheKey:fileKeyFromUrl]) {
        /*
         
         [self.cache checkIfShouldUseCacheWithCacheDuration:cacheDuration cacheKey:fileKeyFromUrl]
         這個方法如果返回nil俄烁,說明緩存無效绸栅。
         如果返回了數(shù)據(jù),那么緩存是有效猴娩。
         
         */
       // NSMutableDictionary *localCache = [NSMutableDictionary dictionary];
        NSDictionary *cacheDict = [self.cache searchCacheWithUrl:fileKeyFromUrl]; // 讀緩存
       // [localCache setDictionary:cacheDict];
        if (cacheDict) {
            completionHandler(nil, YES, cacheDict); // error阴幌, isCache勺阐, result
            return; // 注意到這里已經(jīng)結(jié)束了,不走下面
        }
    }
    
    // 處理AF請求到的網(wǎng)絡(luò)數(shù)據(jù)矛双,是否緩存之類的
    SYRequestCompletionHandler newCompletionBlock = ^(NSError* error, BOOL isCache, NSDictionary *result){
        
        result = [NSMutableDictionary dictionaryWithDictionary:result];
        //3.1處理網(wǎng)絡(luò)數(shù)據(jù)是否存入緩存(如果cacheDuration時效大于0渊抽,網(wǎng)絡(luò)數(shù)據(jù)就存入到緩存中)
        if (cacheDuration > 0) {
            
            // 假如網(wǎng)絡(luò)數(shù)據(jù)有問題,那么網(wǎng)絡(luò)數(shù)據(jù)不應(yīng)該保存緩存里面
            // 因為不同的業(yè)務(wù)有不同錯誤code碼
            
            if (weakSelf.cacheConditionBlock) { // 緩存條件
                
                 // 如果把服務(wù)端返回的code代入判斷block
                if (weakSelf.cacheConditionBlock(result)) {
                    [weakSelf.cache saveCacheData:result forKey:fileKeyFromUrl];
                }
            }else{
              // 如果外部沒有判斷block议忽,默認任務(wù)數(shù)據(jù)存入緩存(不推薦)
                [weakSelf.cache saveCacheData:result forKey:fileKeyFromUrl]; // 存入緩存
            }
        }
            
        // 1 異常條件
        if(weakSelf.exceptionBlock){
            weakSelf.exceptionBlock(error, result);
        }
        
        completionHandler(error, isCache, result);

    };
    
    
    
    //3  發(fā)起AF網(wǎng)絡(luò)任務(wù)
    NSURLSessionTask *task = nil;
    if ([method isEqualToString:@"GET"]) {
        
        task = [self.afHttpManager GET:urlStr parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            // 3.1處理網(wǎng)絡(luò)數(shù)據(jù)是否存入緩存
           // completionHandler(nil, NO, responseObject);
            newCompletionBlock(nil, NO, responseObject);
           
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            
            //completionHandler(error, NO, nil);
            newCompletionBlock(error, NO, nil);
        }];
        
    }else{
        
        task = [self.afHttpManager POST:urlStr parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
          //  completionHandler(nil, NO, responseObject);
            newCompletionBlock(nil, NO, responseObject);
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            
           // completionHandler(error, NO, nil);
            newCompletionBlock(error, NO, nil);
        }];
        
    }
    
    [task resume];
}

5.NSCache

  • 緩存方面使用包含NSCache屬性的單例懒闷,主要是在系統(tǒng)內(nèi)存資源緊張的時候會自動釋放內(nèi)存
  • 其他方面NSCache與一般容器類型,如NSDictionary

6.其他需要注意的地方

  • 這邊判斷是否是有緩存存在時栈幸,先從cache找愤估,再從本地找(這里采用歸檔做法)
  • 儲存緩存時cache與本地同時存儲一份
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市速址,隨后出現(xiàn)的幾起案子玩焰,更是在濱河造成了極大的恐慌,老刑警劉巖芍锚,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昔园,死亡現(xiàn)場離奇詭異,居然都是意外死亡并炮,警方通過查閱死者的電腦和手機默刚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來逃魄,“玉大人荤西,你說我怎么就攤上這事∥榉” “怎么了邪锌?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長养篓。 經(jīng)常有香客問我秃流,道長赂蕴,這世上最難降的妖魔是什么柳弄? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮概说,結(jié)果婚禮上碧注,老公的妹妹穿的比我還像新娘。我一直安慰自己糖赔,他們只是感情好萍丐,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著放典,像睡著了一般逝变。 火紅的嫁衣襯著肌膚如雪基茵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天壳影,我揣著相機與錄音拱层,去河邊找鬼。 笑死宴咧,一個胖子當著我的面吹牛根灯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播掺栅,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼烙肺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了氧卧?” 一聲冷哼從身側(cè)響起桃笙,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎沙绝,沒想到半個月后怎栽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡宿饱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年熏瞄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谬以。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡强饮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出为黎,到底是詐尸還是另有隱情邮丰,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布铭乾,位于F島的核電站剪廉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏炕檩。R本人自食惡果不足惜斗蒋,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望笛质。 院中可真熱鬧泉沾,春花似錦、人聲如沸妇押。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽敲霍。三九已至俊马,卻和暖如春丁存,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背柴我。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工柱嫌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人屯换。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓编丘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親彤悔。 傳聞我的和親對象是個殘疾皇子嘉抓,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

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