亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

利用內存結構及多線程優化多圖片下載(IOS篇)

2019-11-14 18:43:05
字體:
來源:轉載
供稿:網友

利用內存結構及多線程優化多圖片下載(IOS篇)

前言

下載地址, 后續發布, 請繼續關注本blog

在IOS中,我們常常遇到多圖片下載的問題。最簡單的解決方案是直接利用別人寫好的框架。但是這如同練武,只練外功而不練內功。在這些框架中,SDWebImage這個框架是比較常用的框架,對于該框架的使用,不在這再做詳細介紹。主要從計算機的視角和多線程引發的一些問題來分享下如何自己做,或者說SDWebImage大體上也是基于這種方式來做的。在這之前,有必要先說下一些操作系統的基本架構和原理。

內存結構

其實在操作系統中,所謂的內存結構,不是指我們電腦中的內存。在專業術語中,電腦中的內存稱為主存。而內存結構指的是由磁盤+主存+緩存構成的結構。在這個構架中,從磁盤的速度比主存的速度慢,而主存的速度又比緩存的速度慢。這三種存儲物質也是由不同的材料所做成,所以緩存的價格大于主存的價格,而主存又大于磁盤的價格。要不然你都可以把電腦磁盤替換成內存了,那將是十分的快,當然的保證你電腦是不斷電的。所以程序啟動的時候,都是從磁盤中讀取數據,到主存中完成整個程序的加載,這時候,程序就在主存中。

重點

同樣的道理,我們在做App的時候,對于圖片下載這種問題。我們深知,必須得使用多線程來下載圖片,然后另外一個線程來刷新界面。這才不會導致因為下載事件過長而引起的界面十分不流暢。同時,我們為了避免重復的下載圖片,為用戶節省流量,并且也為了提高圖片的加載速度。我們有必要利用內存結構的特點來解決這個問題。所以對于這種問題,我們主要的思路就是1.將下載的圖片緩存到主存中開辟的一塊緩存圖片的空間。進行UI渲染的時候到緩存中取到對應的圖片,渲染UI界面。

判斷邏輯過程如下:

1.先判斷主存緩存中有沒有圖片,如果沒有進行第二步

2.判斷磁盤有沒有緩存的圖片,如果有將其加載進內存,并緩存到主存中的緩存圖片的位置。如果沒有進行第三步

3.從網絡中下載圖片,并緩存到內存和磁盤上。

4.應用程序需用用到圖片的時候,直接從內存中的緩存圖片的位置拿。

存在的問題:

A.第一個是需要用子線程來下載圖片,主線程進行渲染, 從而提高程序流暢性。

B.第二個是解決因為圖片過大或者圖片數據下載過慢時候,圖片還沒有下載完,還沒緩存到內存中時候。用戶不斷拖拽TableView,

由于UITableViewCell循環利用,使得在進行判斷1的時候,重復下載圖片。


C.第三個是將主存中的圖片緩存寫入磁盤在渲染UI之前,但是我們可以為期在開個線程讓兩個同時進行,提高程序的效率。

對于第一個問題,很好解決。請看代碼, 這是自定義cell中針對傳入模型數據進行的處理。只需關注該重點,想要測試程序自行到我的github上下載,如果你覺得這個程序對你有學習價值,記得給個star。

因為不想重復的粘貼代碼,所以以下代碼是最終版本的核心代碼,但是為了說明問題。問題重現,所以請跟著我的步驟來,一步步的打開被注釋的代碼,觀察效果?,F在請你忽略所有注釋的代碼,先搞懂這是為了解決問題A。

- (void)setApp:(SWPApp *)app {        _app = app;        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{                // 1.子線程下載數據        SWPCache * cache = [SWPCache sharedInstance];                // 1.1內存無緩存       // if ( cache.imageCache[app.icon] == nil ) {                                    NSString * folderPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];                        NSString * filePath = [folderPath stringByAppendingPathComponent:[app.icon lastPathComponent]];                        BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath: filePath];                        if (!fileExists) [self loadImageWithURLOrFilePath:app.icon isFilePath: NO]; // 1.2 磁盤無緩存則從網絡下載            else [self loadImageWithURLOrFilePath:filePath isFilePath: YES]; // 1.3 磁盤有緩存, 直接加載進內存中的緩存      // }              //  [NSThread sleepForTimeInterval: 1];                // 2.主線程渲染cell的UI        dispatch_async(dispatch_get_main_queue(), ^{                       self.textLabel.text = app.name;                    self.imageView.image = cache.imageCache[app.icon];                        self.detailTextLabel.text = app.download;                    });                    });    }- (void)loadImageWithURLOrFilePath:(NSString *)url isFilePath:(BOOL)isFilePath {            SWPCache * cache = [SWPCache sharedInstance];    NSData * data = nil;    // 1.先判斷下載該圖片的操作是否已經執行過    // 如果執行過, 那么圖片緩存中必定存在圖片.   // if (!cache.OperationCache[self.app.icon]) {        static int i = 0;        NSLog(@"---%d", i);        data = isFilePath ? [NSData dataWithContentsOfFile: url]                          : (i++, [NSData dataWithContentsOfURL: [NSURL URLWithString: url ]]);                // 如果數據下載失敗        if (!data) {                        [cache.operationCache removeObjectForKey: self.app.icon];                    } else {                    UIImage * image = [UIImage imageWithData: data];                        cache.imageCache[self.app.icon] = image;                        cache.operationCache[self.app.icon] = [NSNumber numberWithBool: true];                                    //  if (!isFilePath) {                // 1.為讓其一邊顯示一邊寫入                //dispatch_async(dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{                    [data writeToFile:url atomically: YES];               //  });           // }                    }                  //  }    }

解決完UI界面的流暢度問題,我們就需要利用內存結構來節約用戶流量和提高UI再次渲染的速度。

所以此時,還沒將圖片緩存到主存中,所以請看下面動態圖。再將第12,24行打開,再看第二種動態圖會發現,打印值只到16,也就是所只下載了16次圖片。這就大大提高了的說明了能節約用戶流量和提高UI再次渲染的速度。。如下圖(沒加入主存時候)

分析B: 接著我們來看問題B。也許這時候你覺得程序已經不存在問題了,確實,現在的程序是不存在問題了,但是可能會遇到問題。就是遇到一種十分極端的情況,這種情況可以通過斷網來進行模擬。(模擬數據量過大,或者下載速度太慢,此時用戶不斷滾動TableView)會造成,因為圖片沒下載好,也就還沒緩存到主存,所以當要取圖片的時候,到主存對應的位置去取,卻發現沒有,這時候,就會調用網絡下載,下載圖片,就造成了不斷重復的下載。如下圖

解決B這時候我們就需要某種標志來,標志該下載已經存在,不需要重新下載。所以我用了一個字典來映射各個下載圖片的操作,在下載操作執行前從字典中取出,判斷有沒有該操作,有則不重復下載。這是可以打開第52,和82行即可,觀察到效果。(記得打開網絡!)如下圖

分析C: 其實C問題所起來很好解決,閱讀我的源代碼,你可以看到第75行是在當前線程中寫入數據到磁盤,這就造成了,要等待該寫入操作完成后才退出該函數,接著才將渲染任務交給主線程。但是寫入操作和渲染操作其實是可以同時進行的。所以我們可以在這里使用異步函數

解決C:打開對應的注釋(72和77), 驗證就不在做了,可以自己打印時間觀察。

所以對于多圖片下載的問題我們主要是這么做:1.通過多線程的方式,解決UI能流暢渲染,。2.通過利用內存構架提高UI渲染的速度,并且解決了第一種圖片重復下載問題。3.通過標記操作,實現同一下載互斥,解決UITableViewCell重用機制造成的第二種圖片重復下載問題。

具體判斷邏輯與細節:

1.先判斷主存緩存中有沒有圖片,如果沒有進行第二步

2.判斷磁盤有沒有緩存的圖片,如果有則直接加載進主存緩存中,并記錄該次操作,如果沒有進行第三步。

3.先判斷該下載操作是否存在,如果存在,則不進行下載操作。如果不存在進行第四步。

4.從網絡中下載圖片,并且判斷下載是否成功,如果成功下載,則記錄該次下載操作,實現互斥。再將圖片寫入主存緩存,并開啟另外一個線程將圖片寫入磁盤。

如果沒有下載成功或者從磁盤中沒有加載成功,則移除該次的下載標志, 解除該次下載互斥。


5.主線程直接從主存中的圖片緩存位置來圖片,渲染到UI界面。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩最新中文字幕电影免费看| 国产丝袜一区二区三区| 国产成人精品电影久久久| 九九九热精品免费视频观看网站| 国产成人综合亚洲| 欧美日韩国内自拍| 欧美性极品xxxx娇小| 国产精品伦子伦免费视频| 91影视免费在线观看| 57pao成人国产永久免费| 日韩成人在线观看| 国产精品国语对白| 日韩精品在线观看一区二区| 亚洲欧美三级伦理| 亚洲精品v天堂中文字幕| 国产精品久久久久久久久久久不卡| 久精品免费视频| 色综合久久天天综线观看| 国产成人免费av电影| 亚洲美女激情视频| 欧美孕妇毛茸茸xxxx| 尤物九九久久国产精品的特点| 欧美网站在线观看| 国产精品99久久99久久久二8| 在线观看欧美www| 精品亚洲一区二区三区| 精品国产一区二区三区久久| 国产欧美一区二区三区在线| 2019中文在线观看| 欧美亚洲视频在线观看| 欧美在线亚洲在线| 久久伊人91精品综合网站| 国产香蕉97碰碰久久人人| 亚洲成在人线av| 欧美日韩一区二区精品| 亚洲丝袜在线视频| 91国产美女在线观看| 亚洲色图色老头| 一本色道久久88综合日韩精品| 国产日本欧美一区二区三区在线| 九色91av视频| 欧美专区第一页| 欧美精品久久一区二区| 国产69精品久久久| 国产精品一区二区三区成人| 综合136福利视频在线| 成人在线小视频| 精品国产依人香蕉在线精品| 色天天综合狠狠色| 自拍亚洲一区欧美另类| 亚洲国语精品自产拍在线观看| 国产精品免费一区二区三区都可以| 亚洲人成五月天| 97视频免费在线看| 日韩久久免费电影| 91中文在线观看| 国产丝袜精品第一页| 亚洲精品一区在线观看香蕉| 尤物精品国产第一福利三区| 亚洲国产成人精品电影| 欧美成人网在线| 在线精品高清中文字幕| 亚洲四色影视在线观看| 日韩激情av在线免费观看| 中文字幕视频在线免费欧美日韩综合在线看| 亚洲欧美日本另类| 欧美性xxxx18| 亚洲女成人图区| www国产91| 在线亚洲国产精品网| 亚洲人成在线观看| 欧美国产日本在线| 欧洲成人在线观看| 国产成人在线播放| 色综合天天狠天天透天天伊人| 精品久久久久久久久久久| 色综合亚洲精品激情狠狠| 最新中文字幕亚洲| 热久久免费国产视频| 欧美成人剧情片在线观看| 国产成人精品电影| 夜色77av精品影院| 亚洲视频一区二区三区| 少妇精69xxtheporn| 欧美性猛交xxxx乱大交3| 尤物九九久久国产精品的特点| 日本一区二三区好的精华液| 美女999久久久精品视频| 亚洲免费视频网站| 在线一区二区日韩| 91精品综合久久久久久五月天| 日韩最新在线视频| 国产精品r级在线| 国产91精品不卡视频| 免费成人高清视频| 日韩精品福利在线| 国产91色在线|| 琪琪亚洲精品午夜在线| 久久久电影免费观看完整版| 欧美日韩中文在线观看| 人人做人人澡人人爽欧美| 日韩中文理论片| 日韩人体视频一二区| 国产精品直播网红| 久久网福利资源网站| 久久精品亚洲热| 精品福利免费观看| 日韩在线免费观看视频| 国产情人节一区| 国产精品入口日韩视频大尺度| 国产精品视频网址| 欧美电影免费观看大全| 日韩精品一区二区三区第95| 久久网福利资源网站| 最近2019年好看中文字幕视频| 久久国产视频网站| 97精品国产97久久久久久| 在线观看精品国产视频| 欧美性20hd另类| 亚洲一区二区少妇| 日韩电影免费在线观看中文字幕| 欧美中文在线视频| 国产性猛交xxxx免费看久久| 日韩av在线精品| 日韩精品免费在线视频| 日韩暖暖在线视频| 最新69国产成人精品视频免费| 国产精品成人aaaaa网站| 青青久久av北条麻妃海外网| 中文字幕欧美日韩va免费视频| 精品日本美女福利在线观看| 久久99久国产精品黄毛片入口| 久久人91精品久久久久久不卡| 欧美福利视频网站| 欧美大片免费看| 国产亚洲欧洲高清一区| 国产成人亚洲综合| 国产精品91免费在线| 中文字幕精品—区二区| 亚洲精品久久久久久久久久久久| 欧美福利视频在线观看| 成人网欧美在线视频| 日韩成人激情视频| 九色91av视频| 亚洲精品欧美一区二区三区| 国产精品久久国产精品99gif| 欧美激情一区二区三区成人| 疯狂做受xxxx高潮欧美日本| 国产精品无av码在线观看| 国内精品美女av在线播放| 亚洲视频综合网| 97视频免费在线观看| 日韩在线视频网| 欧美富婆性猛交| 国产成人精品av| 色综合影院在线| 欧美片一区二区三区| 欧美成人剧情片在线观看| 国产精品精品一区二区三区午夜版| 欧美成人四级hd版| 精品视频中文字幕| 亚洲黄色av女优在线观看| 国产精选久久久久久| 日韩午夜在线视频|