iOS圖片加載策略的簡(jiǎn)單實(shí)現(xiàn)(轉(zhuǎn))

邏輯如圖:


圖片.png

問(wèn)題總結(jié):

  • 圖片重復(fù)下載,通過(guò)添加的打印可以很明顯的看出來(lái)呵曹,解決方式是把之前下載好的圖片保存起來(lái),因?yàn)閳D片和文字要對(duì)應(yīng)铐殃,所以采用字典的方式進(jìn)行存儲(chǔ)跨新。
    1、添加內(nèi)存緩存解決圖片重復(fù)下載問(wèn)題
    2赘被、添加內(nèi)存緩存存在問(wèn)題肖揣,需要用磁盤緩存(沙盒緩存)來(lái)補(bǔ)充
    3、UI不流暢羊异,因?yàn)橄螺d圖片操作和刷新UI的操作都是在主線程中操作的彤断,解決方法把下載操作放到子線程中進(jìn)行操作。

  • UI不會(huì)自動(dòng)刷新平道,當(dāng)我拖動(dòng)的時(shí)候才會(huì)刷新頁(yè)面巢掺,解決方式要使用代碼手動(dòng)刷新劲蜻。
    因?yàn)橄螺d操作是異步的,會(huì)先把沒(méi)有圖標(biāo)的cell返回轧苫,此時(shí)因?yàn)閳D標(biāo)的frame為0疫蔓,所以之后即使圖片下載下來(lái),frame變?yōu)槠渌~尺寸衅胀,frame還是會(huì)一直為0滚躯,所以不會(huì)顯示嘿歌。如果我手動(dòng)刷新宙帝,系統(tǒng)會(huì)從新走一遍cellForRowAtIndexPath:方法募闲,到設(shè)置圖標(biāo)這一步時(shí),會(huì)直接把內(nèi)存中存在的圖片(此時(shí)圖片是有frame的)直接設(shè)置到cell中會(huì)顯示靴患。

  • 由于拖動(dòng)太快蚁廓,導(dǎo)致的重復(fù)下載的問(wèn)題厨幻。解決方式是定義一個(gè)操作緩存(字典)况脆,把之前的操作都保存起來(lái)批糟,因?yàn)樯厦娉霈F(xiàn)的原因本質(zhì)就是因?yàn)閎lockOperation重復(fù)添加到queue中了。
    這個(gè)問(wèn)題是這樣的盛末,需要顯示的圖片會(huì)進(jìn)行下載操作否淤,但是一張圖片下載需要時(shí)間,如果圖片還沒(méi)下載下來(lái)檐嚣,我就拖動(dòng)了嚎京,將它移出屏幕隐解,結(jié)果就是這張圖片沒(méi)有下載完,如果這時(shí)候我又拖動(dòng)了帕涌,又要顯示這張圖片,因?yàn)樯弦淮芜€沒(méi)下載完架谎,所以內(nèi)存和磁盤里都沒(méi)有谷扣,所以會(huì)重復(fù)下載捎琐。解決方式是定義一個(gè)操作緩存(字典),把之前的操作都保存起來(lái)末秃,因?yàn)樯厦娉霈F(xiàn)的原因本質(zhì)就是因?yàn)閎lockOperation重復(fù)添加到queue中了籽御。

  • cell的重用機(jī)制導(dǎo)致的cell圖標(biāo)展示數(shù)據(jù)錯(cuò)亂的問(wèn)題,解決方案铃将,如果要進(jìn)行下載圖片劲阎,先清空原來(lái)cell上的圖片鸠真,但是一般不會(huì)直接設(shè)置為nil,會(huì)采用占位圖片的方式來(lái)解決吠卷。

最終完成版:

/** 定義操作緩存屬性 */
    @property (nonatomic, strong) NSMutableDictionary *operations;
    // 操作緩存屬性懶加載實(shí)現(xiàn)
    - (NSMutableDictionary *)operations{

        if (!_operations) {
            _operations = [NSMutableDictionary dictionary];
        }
    
        return _operations;
    }
    // 設(shè)置圖標(biāo)的位置修改如下:
    // 先去查看內(nèi)存緩存中該圖片有沒(méi)有被下載過(guò)撤嫩,如果有直接拿來(lái)用,如果沒(méi)有就去檢查磁盤緩存茴她,如果沒(méi)有磁盤緩存程奠,就保存一份到內(nèi)存瞄沙,設(shè)置圖片慌核,否則就直接下載垮卓。
    UIImage *image = [self.images objectForKey:item.icon];
    // 如果有值直接拿來(lái)直接使用
    if(image){

        cell.imageView.image = image;
        NSLog(@"使用了內(nèi)存緩存中的圖片----%zd",indexPath.row);

    }else{
        
        // 沙盒緩存路徑獲取(磁盤緩存)
        NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
        // 獲得圖片的名稱
        NSString *imageName = [item.icon lastPathComponent];
        // 拼接全路徑
        NSString *fullPath = [cachePath stringByAppendingPathComponent:imageName];
        // 檢查磁盤緩存
        NSData *imageData = [NSData dataWithContentsOfFile:fullPath];
        if (imageData) {
            // 設(shè)置圖標(biāo)
            UIImage *image = [UIImage imageWithData:imageData];
            cell.imageView.image = image;
            NSLog(@"沙盒存儲(chǔ)----%zd",indexPath.row);
            // 保存圖片到內(nèi)存緩存
            [self.images setObject:image forKey:item.icon];  

             }else{

                // 檢查圖片是否在操作緩存中進(jìn)行下載粟按,如果在下載就什么也不做灭将,如果不在就添加下載任務(wù)
                NSBlockOperation *blockOperation = [self.operations objectForKey:item.icon];
                if (blockOperation) {
                
                }else{

                    // 防止cell重用導(dǎo)致的數(shù)據(jù)錯(cuò)亂 先設(shè)置cell 的 image為空
                    cell.imageView.image = [UIImage imageNamed:@"placeHolder.png"];
                    // 創(chuàng)建下載操作
                    blockOperation = [NSBlockOperation blockOperationWithBlock:^{
                    NSURL *url = [NSURL URLWithString:item.icon];
                    NSData *imageData = [NSData dataWithContentsOfURL:url];
                    UIImage *image = [UIImage imageWithData:imageData];
                    NSLog(@"下載------%@",[NSThread currentThread]);
                    // 當(dāng)url地址不正確 image為空 容錯(cuò)處理
                    if (!image) {
                        // 為了下一次進(jìn)來(lái)的時(shí)候再次嘗試進(jìn)行圖片下載
                        [self.operations removeObjectForKey:item.icon];
                        return ;
                    }
                      [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                            cell.imageView.image = image;
                            NSLog(@"UI------%@",[NSThread currentThread]);
                            // 手動(dòng)刷新 刷新UITableView指定的行
                            [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationRight];
                        }];
                    // 保存圖片到內(nèi)存緩存 用圖片的URL作為圖片的key 保證key唯一
                    [self.images setObject:image forKey:item.icon];
                     // 保存圖片到沙盒緩存(磁盤緩存)
                     [imageData writeToFile:fullPath atomically:YES];
                     // 下載操作完成后進(jìn)行移除操作
                    [self.operations removeObjectForKey:item.icon];
                     }];
                    // 添加下載操作到操作緩存中
                    [self.operations setObject:blockOperation forKey:item.icon];
                    // 添加下載操作到并發(fā)隊(duì)列中
                    [self.queue addOperation:blockOperation];
            
        }   
    } 
}
  • 內(nèi)存問(wèn)題:將圖片保存在內(nèi)存中是很方便的事,圖片少的情況下肯定沒(méi)問(wèn)題捌朴,但是圖片多了就會(huì)內(nèi)存警告张抄,要做一下處理。
- (void)didReceiveMemoryWarning{
    // 移除內(nèi)存緩存,這里不會(huì)影響界面顯示泽台,因?yàn)橛袕?qiáng)引用的關(guān)系矾缓。
    [self.images removeAllObjects];
    // 移除隊(duì)列中所有操作
    [self.queue cancelAllOperations];
}

原貼寫的更清晰相近嗜闻,轉(zhuǎn)自:http://www.reibang.com/p/6edf6b9b2c1b

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末琉雳,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子翠肘,更是在濱河造成了極大的恐慌束倍,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件甥桂,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡蝇摸,警方通過(guò)查閱死者的電腦和手機(jī)探入,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門蜂嗽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)殃恒,“玉大人,你說(shuō)我怎么就攤上這事离唐。” “怎么了完沪?”我有些...
    開(kāi)封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵覆积,是天一觀的道長(zhǎng)宽档。 經(jīng)常有香客問(wèn)我庵朝,道長(zhǎng)吗冤,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任九府,我火速辦了婚禮椎瘟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘侄旬。我一直安慰自己降传,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布勾怒。 她就那樣靜靜地躺著婆排,像睡著了一般声旺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上段只,一...
    開(kāi)封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天腮猖,我揣著相機(jī)與錄音,去河邊找鬼姐赡。 笑死项滑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的州疾。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起瘩蚪,我...
    開(kāi)封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤巡球,失蹤者是張志新(化名)和其女友劉穎险胰,沒(méi)想到半個(gè)月后棚贾,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體妙痹,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡震贵,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年中燥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拿霉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡沪铭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赔退,到底是詐尸還是另有隱情,我是刑警寧澤慧域,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布碘橘,位于F島的核電站,受9級(jí)特大地震影響吐葵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜凤藏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一蹄梢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦桂塞、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春玻淑,著一層夾襖步出監(jiān)牢的瞬間补履,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工五鲫, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留乱灵,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓嗡髓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

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

  • 今天和大家一起來(lái)討論如何進(jìn)行iOS圖片加載策略的簡(jiǎn)單實(shí)現(xiàn)先巴,有疏忽的地方,還望各位不吝賜教摇幻。 一狂芋、不自量力的說(shuō)明 對(duì)...
    聽(tīng)海聽(tīng)心閱讀 1,395評(píng)論 4 8
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件灭衷、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,029評(píng)論 4 62
  • 前言 在上一篇文章Android狀態(tài)保存與恢復(fù)流程 完全解析,筆者詳細(xì)地介紹了Activity、Fragment、...
    丶藍(lán)天白云夢(mèng)閱讀 4,601評(píng)論 5 42
  • 大千世界奢讨,人流涌動(dòng);或許是上一世的回眸換來(lái)了今生有你作我的室友。緣分使然我們相識(shí)于大學(xué)里的小家飒泻。 夏日炎炎席覆,提著拉...
    溯光之舟閱讀 266評(píng)論 0 1
  • 跟一個(gè)朋友交流,說(shuō)自己一天下來(lái)甸陌,總是感覺(jué)很忙碌寥院,也很充實(shí),但卻會(huì)出現(xiàn)空虛感。追問(wèn)為何空虛,回答曰“就是忙了一天,看...
    逄格亮閱讀 223評(píng)論 0 0