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

首頁 > 系統 > iOS > 正文

IOS Cache設計詳細介紹及簡單示例

2020-07-26 02:59:37
字體:
來源:轉載
供稿:網友

IOS Cache設計

Cache的設計是個基礎計算機理論,也是程序員的重要基本功之一。Cache幾乎無處不在,CPU的L1 L2 Cache,iOS系統的clean page和dirty page機制,HTTP的tag機制等,這些背后都是Cache設計思想的應用。

為什么需要Cache

Cache的目的是為了追求更高的速度體驗,Cache的源頭是兩種數據讀取方式在成本和性能上的差異。

在開始著手設計Cache之前,需要先理清數據存儲的媒介。作為客戶端開發人員來說,我們所關注的數據存儲方式也有不少種:

  • 數據最開始是存儲在Server上,這些數據需要通過網絡請求獲取。
  • 從Server獲取數據時,會經過各種中間網絡節點(比如代理),這些節點有時會緩存我們的數據。
  • 把數據下載到本地之后,我們會在本地disk緩存一份,這樣或許不用每次都重新去服務器請求。
  • 存到disk之后,數據的存儲方式會影響到讀取的速度,以B+ Tree存儲的sqlite就比直接序列化NSArray到文件之中要快不少。
  • App啟動時,系統會將從Server下載到的數據,從disk加載到memory,memory的讀寫性能比disk要快很多。
  • 到了Memory中,不同的數據結構存儲方式也會存在速度上的差異。用NSDictionary(hash表)形式存儲讀數據,寫性能都比Array好,但space開銷更大。雖說memory的讀寫性能比disk都高了很多,但在大集合類數據操作的時候有時也會遇到瓶頸。
  • 比Memory更快的還有Register,L1,L2,只不過對于iOS App開發來說,很少深入到這一層面的優化。

上面所說的每一個環節,都存在性能和成本上的差別,Server的數據自然是最及時最準確的,但一個App要以NSArray的形式獲取到Server的數據,中間要經過「漫長」的過程,可以說每一步中都存在cache的設計思想。

對于Cache的理解和實踐,前提是我們對于存儲媒介,和不同數據結構差異,有比較深入的掌握。

我們大部分App的性能優化,如果涉及到Cache,一般都是在Memory這一媒介上做處理。將需要從Disk中,或者通過CPU復雜計算才能獲取的數據,通過合理的數據結構存儲在Memory中,就能解決我們App開發里,絕大部分的Cache需求了。這一層面的Cache設計也有著不同的姿勢,先來看看簡單可用型。

簡單可用型Cache

得益于Foundation中NSDictionary的封裝,我們可以用hash表這種數據結構來實現一個簡單可用的cache機制,先來看一個實例:

- (NSString*)getFormmatedPhoneNumber:(NSNumber*)phone{ if(phone == nil) {  return nil;   }  return [PhoneFormatLib formatPhoneNumber:phone]; //CPU費時操作}

這是個簡單的格式化手機號碼的函數,其中 formatPhoneNumber 函數是個CPU Intensive的調用,而且在業務場景中針對同一個手機號碼,需要經常性的獲取格式化之后的NSString,如果每次都重復計算顯然是對CPU資源的浪費,而且性能也不好。我們可以加個簡單的Cache來優化:

static NSMutableDictionary* gPhoneCache = nil;- (NSString*)getFormmatedPhoneNumber:(NSNumber*)phone{  if(phone == nil)  {    return nil;  }    NSString* phoneNumberStr = nil;    [_phoneLock lock];  if(gPhoneCache == nil)  {    gPhoneCache = @{}.mutableCopy;  }    phoneNumberStr = [gPhoneCache objectForKey:phone];  if (phoneNumberStr == nil) {    phoneNumberStr = [PhoneFormatLib formatPhoneNumber:phone];    [gPhoneCache setObject:phoneNumberStr forKey:phone];  }  [_phoneLock unlock];    return phoneNumberStr; }

通過引入NSMutableDictionary,就避免了每次都需要重復調用 formatPhoneNumber 的問題,so easy就完成了一個快速的cache設計,馬上就可以提交給測試,把優化成果甩產品經理臉上,這歸功于hash表O(1)的時間復雜度。內存空間會多消耗一些,不過對于小量的數據影響比較小,現代的hash表不會一開始就分配大量的空間,而是隨著數據的增加而逐漸擴容。

這種簡單可用型的Cache設計,最大的問題在于,代碼過于零散且不可控。小量且分散的cache設計幾乎等同于挖坑,在你設計cache的時候可能數據量還小,但后面維護的時候,業務改變的時候,誰也不能保證這塊內存的開銷依然可以忽略不計。而且這種內存方面的損耗很難察覺,巧妙的隱蔽在某個.m文件中,到后期想控制整個App的內存開銷時,會感覺到處都有坑,無從下手。你可能也發現了,上面這段Cache代碼沒有釋放Cache的地方。

所有對我們整個App有副作用的代碼都需要被集中管理,要能從架構的層面去理解和定位。怎么去定義副作用呢?可以抽象成一種「寫操作」,往Cache中添加新的記錄就是寫操作,這種寫操作的副作用是額外的內存開銷,Cache的本質是以空間換時間,這空間損耗就是我們的副作用,一個副作用會引發其他更多的副作用,理清這些副作用往往需要反復查閱大量的代碼。更好的辦法是,一開始就把有副作用的代碼集中管理。

優雅可控型Cache

避免Cache代碼散亂放置的做法是,設計一個優雅可控的Cache模塊。一個App中,可能會有各種各樣的數據需要Cache,phoneNumberCache,avatarCache,spaceshipCache等等,我們需要有個源頭來追蹤這些cache,直觀的做法是通過工廠類來生成和持有這些各式各樣的cache:

//CacheFactory.h@interface CacheFactory : NSObject+ (instancetype)sharedInstance;- (id<MyCacheProtocol>)getPhoneNumberCache;- (void)clearPhoneNumberCache;- (id<MyCacheProtocol>)getAvatarCache;- (void)clearAvatarCache;@end

這樣當我們需要評估各種Cache對整個App內存開銷的影響之時,只需要從CacheFactory代碼著手即可,調試起來也有跡可循,其他工程師接手你的代碼也會感激涕零的。

通過protocol的方式,將cache的聲明和實現想分離,這也是個好習慣。cache的另一個重要知識點是cache的淘汰策略,不同的策略表現也不一樣,FIFO,LRU,2Queues等等,現在有不少成熟的第三方cache框架可以使用,系統也提供了淘汰策略不明確的NSCache,如果沒有動手寫過任何cache淘汰策略,我還是建議大家自己動手試著做一個,至少要讀一下相關的實現源碼,了解這些淘汰策略很有必要,在做一些深度優化的時候需要因地制宜來做決定。

cache的使用要有收有放,不能只創建不釋放,事實上,所有涉及到data的操作都要考慮data的生命周期。我們做業務的時候,多是以Controller為基礎單位,有些場景下,一個Controller在退出之后被再次進入的可能性就非常之低了,適時的清理cache會讓我們App的整體表現更好。

Immutable Cache

Cache中存放的是啥?是Data。說到Data,就不得不提peak君最愛亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

国产精品678| 精品网站999www| 久久综合色影院| 久久精品99久久久久久久久| 亚洲人成绝费网站色www| 日本一区二区在线播放| 最近更新的2019中文字幕| 亚洲欧美成人在线| 色哟哟亚洲精品一区二区| 亚洲国产另类 国产精品国产免费| 日韩精品免费观看| 91在线观看免费| 亚洲精品久久久久国产| 97久久久免费福利网址| 亚洲视频999| 欧美亚洲国产另类| 国产999精品久久久| 最近的2019中文字幕免费一页| 97在线精品国自产拍中文| 久久久爽爽爽美女图片| 国产亚洲日本欧美韩国| 久久精品99国产精品酒店日本| 久久影视电视剧凤归四时歌| 日韩精品视频免费专区在线播放| 国产亚洲精品一区二区| 日韩中文字幕第一页| 亚洲国产小视频在线观看| 在线观看中文字幕亚洲| 夜夜躁日日躁狠狠久久88av| 成人日韩在线电影| 欧美性感美女h网站在线观看免费| 国产视频999| 日韩美女在线观看一区| 欧美另类在线观看| 亚洲精品福利在线观看| 91精品国产一区| 国产精品美女999| 国产精品视频免费在线观看| 少妇高潮久久77777| 日韩免费在线免费观看| 日韩黄色av网站| 亚洲一区二区福利| 亚洲精品短视频| 欧美疯狂xxxx大交乱88av| 欧美黄网免费在线观看| 欧美日韩在线影院| 午夜免费在线观看精品视频| 欧美最顶级丰满的aⅴ艳星| 精品国产91久久久久久| 欧美日本高清一区| 亚洲国产精品久久久| 欧美日韩精品在线视频| 岛国av午夜精品| 91九色视频导航| 性欧美在线看片a免费观看| 欧美激情aaaa| 精品久久久久久电影| 91大神在线播放精品| 国产一区二中文字幕在线看| 国内成人精品一区| 91高清视频在线免费观看| 97视频网站入口| 91免费综合在线| 永久555www成人免费| 国产视频亚洲视频| 91亚洲精品久久久久久久久久久久| 久久久久久成人| 日韩成人在线网站| 国产激情999| 亚洲视频国产视频| 92国产精品久久久久首页| 国产精品高潮呻吟久久av无限| 欧美电影在线免费观看网站| 亚洲精品美女久久| 日韩毛片中文字幕| 亚洲美女视频网站| 国产精品成人av在线| 亚洲色图狂野欧美| 欧美一级片久久久久久久| 国产日韩中文在线| 日韩中文有码在线视频| 欧美不卡视频一区发布| 欧美福利小视频| 国产欧美精品xxxx另类| 精品国产一区二区三区在线观看| 国产精品视频一区二区高潮| 国产亚洲aⅴaaaaaa毛片| 国产午夜精品一区二区三区| 欧美一级bbbbb性bbbb喷潮片| 亚洲欧美成人网| 欧美高清在线视频观看不卡| 成人激情综合网| 色777狠狠综合秋免鲁丝| 国产精品视频yy9099| 日本久久久久久久| 久久久久久久999| 亚洲欧美日韩久久久久久| 97视频在线播放| 亚洲福利在线看| 国产91成人在在线播放| 亚洲男人天堂2019| 伊人青青综合网站| 成人国产精品久久久久久亚洲| 亚洲国产精品99| 久久久免费观看视频| 91夜夜未满十八勿入爽爽影院| 久久久久久久999| 黑人与娇小精品av专区| 日韩精品在线第一页| 亚洲国产精品999| 欧美人与性动交a欧美精品| 久久久久久综合网天天| 91色琪琪电影亚洲精品久久| 国产日韩在线看片| 成人h片在线播放免费网站| 欧美电影免费观看高清| 伊人久久久久久久久久| 亚洲精品国产欧美| 亚洲综合在线做性| 国产一区二区丝袜高跟鞋图片| 欧洲成人免费视频| 国产精品久久久久久一区二区| 中文字幕9999| www国产精品com| 欧美日韩高清区| 亚洲成人精品久久| 69久久夜色精品国产7777| 国产精品视频自在线| 久久久久久久久久久免费| 91在线观看免费高清完整版在线观看| 国产成人综合一区二区三区| 国产香蕉97碰碰久久人人| 国产一区二区免费| 日韩欧美在线免费| 国产丝袜一区二区三区| 欧美性猛交xxxx免费看| 国语自产精品视频在线看一大j8| 亚洲成色www8888| 久久亚洲国产精品成人av秋霞| 91精品国产777在线观看| 91超碰caoporn97人人| 日韩国产在线看| 国产精品久久久久久av下载红粉| 亚洲欧美视频在线| 久久久亚洲网站| 欧美激情欧美狂野欧美精品| 欧美伊久线香蕉线新在线| 91av在线视频观看| 在线观看视频亚洲| 日韩欧美在线一区| 国产日韩欧美中文在线播放| 亚洲欧洲在线观看| 亚洲色图13p| 亚洲成人性视频| 午夜精品一区二区三区视频免费看| 久久中文字幕在线| 亚洲精品在线不卡| 欧美在线影院在线视频| 欧美成人国产va精品日本一级| 欧美精品videofree1080p| 亚洲精品美女免费| 中文在线资源观看视频网站免费不卡| 国产精品九九久久久久久久| 91tv亚洲精品香蕉国产一区7ujn|