亚洲免费不卡_在线视频精品_国产尤物精品_久久久久网址_久久精品91_欧美va天堂在线_狠狠入ady亚洲精品_亚洲午夜精品福利_国产精品草草_午夜精品久久99蜜桃的功能介绍

IOS緩存機(jī)制詳解
來源:易賢網(wǎng) 閱讀:2037 次 日期:2015-05-08 14:27:47
溫馨提示:易賢網(wǎng)小編為您整理了“IOS緩存機(jī)制詳解”,方便廣大網(wǎng)友查閱!

為什么要有緩存

應(yīng)用需要離線工作的主要原因就是改善應(yīng)用所表現(xiàn)出的性能。將應(yīng)用內(nèi)容緩存起來就可以支持離線。我們可以用兩種不同的緩存來使應(yīng)用離線工作。第一種是**按需緩存**,這種情況下應(yīng)用緩存起請求應(yīng)答,就和Web瀏覽器的工作原理一樣;第二種是**預(yù)緩存**,這種情況是緩存全部內(nèi)容(或者最近n條記錄)以便離線訪問。

像第14章中開發(fā)的Web服務(wù)應(yīng)用利用按需緩存技術(shù)來改善可感知的性能而不是提供離線訪問。離線訪問只是無心插柳的結(jié)果。Twitter和Foursquare就是很好的例子。這類應(yīng)用得到的數(shù)據(jù)通常很快就會過時。對于一條幾天前的推文或者朋友上周在哪里你能有多大興趣?一般來說,一條推文或者一條簽到的信息只在幾個小時內(nèi)有意義,而24小時之后就變得無關(guān)緊要。不過大部分Twitter客戶端還是會緩存推文,而Foursquare的官方客戶端在無網(wǎng)絡(luò)連接的情況下打開,會顯示上次的狀態(tài)。

大家可以用自己喜歡的Twitter客戶端來試一下,Twitter for iPhone、Tweetbot或其他應(yīng)用:打開某個朋友的個人資料并瀏覽他的時間線。應(yīng)用會獲取時間線并填充頁面。加載時間線時會看到一個表示正在加載的圓圈在旋轉(zhuǎn)。現(xiàn)在進(jìn)入另一個頁面,然后再回來打開時間線。你會發(fā)現(xiàn)這次是瞬間加載的。應(yīng)用還是在后臺刷新內(nèi)容(在上次打開的基礎(chǔ)上),但是它會顯示上次緩存的內(nèi)容而不是無趣地轉(zhuǎn)圈,這樣看起來就快多了。如果沒有緩存,用戶每次打開一個頁面都會看到圓圈在旋轉(zhuǎn)。無論網(wǎng)絡(luò)連接快還是慢,減小網(wǎng)絡(luò)加載慢的影響,讓它看起來很快,是iOS開發(fā)者的責(zé)任。這就能大大改善用戶滿意度,從而提高了應(yīng)用在App Store中的評分。

另一種緩存更加重視被緩存數(shù)據(jù),并且能快速編輯被緩存的記錄而無需連接到服務(wù)器。代表應(yīng)用包括Google Reader客戶端,稍后閱讀類的應(yīng)用Instapaper等。

緩存的策略:

上一節(jié)中討論到按需緩存和預(yù)緩存,它們在設(shè)計和實現(xiàn)上有很大的不同。按需緩存是指把從服務(wù)器獲取的內(nèi)容以某種格式存放在本地文件系統(tǒng),之后對于每次請求,檢查緩存中是否存在這塊數(shù)據(jù),只有當(dāng)數(shù)據(jù)不存在(或者過期)的情況下才從服務(wù)器獲取。這樣的話,緩存層就和處理器的高速緩存差不多。獲取數(shù)據(jù)的速度比數(shù)據(jù)本身重要。而預(yù)緩存是把內(nèi)容放在本地以備將來訪問。對預(yù)緩存來說,數(shù)據(jù)丟失或者緩存不命中是不可接受的,比方用戶下載了文章準(zhǔn)備在地鐵上看,但卻發(fā)現(xiàn)設(shè)備上不存在這些文章。

像Twitter、Facebook和Foursquare這樣的應(yīng)用屬于按需緩存,而Instapaper和Google Reader等客戶端則屬于預(yù)緩存。

實現(xiàn)預(yù)緩存可能需要一個后臺線程訪問數(shù)據(jù)并以有意義的格式保存,以便本地緩存無需重新連接服務(wù)器即可被編輯。編輯可能是“標(biāo)記記錄為已讀”或“加入收藏”,或其他類似的操作。這里**有意義的格式**是指可以用這種方式保存內(nèi)容,不用和服務(wù)器通信就可以在本地作出上面提到的修改,并且一旦再次連上網(wǎng)就可以把變更發(fā)送回服務(wù)器。這種能力和Foursquare等應(yīng)用不同,雖然使用后者你能在無網(wǎng)絡(luò)連接的情況下看到自己是哪些地點的地主(Mayor),當(dāng)然前提是進(jìn)行了緩存,但無法成為某個地點的地主。Core Data(或者任何結(jié)構(gòu)化存儲)是實現(xiàn)這種緩存的一種方式。

按需緩存工作原理類似于瀏覽器緩存。它允許我們查看以前查看或者訪問過的內(nèi)容。按需緩存可以通過在打開一個視圖控制器時按需地緩存數(shù)據(jù)模型(創(chuàng)建一個數(shù)據(jù)模型緩存)來實現(xiàn),而不是在一個后臺線程上做這件事。也可以在一個URL請求返回成功(200 OK)應(yīng)答時實現(xiàn)按需緩存(創(chuàng)建一個URL緩存)。兩種方法各有利弊,稍后我會在24.3節(jié)和24.6節(jié)中解釋各個方法的優(yōu)缺點。

選擇使用按需緩存還是預(yù)緩存的一個簡便方法是判斷是否需要在下載數(shù)據(jù)之后處理數(shù)據(jù)。后期處理數(shù)據(jù)可能是以用戶產(chǎn)生編輯的形式,也可能是更新下載的數(shù)據(jù),比如重寫HTML頁面里的圖片鏈接以指向本地緩存圖片。如果一個應(yīng)用需要做上面提到的任何后期處理,就必須實現(xiàn)預(yù)緩存。

存儲緩存:

第三方應(yīng)用只能把信息保存在應(yīng)用程序的沙盒中。因為緩存數(shù)據(jù)不是用戶產(chǎn)生的,所以它應(yīng)該被保存在NSCachesDirectory,而不是NSDocumentsDirectory。為緩存數(shù)據(jù)創(chuàng)建獨立目錄是一項不錯的實踐。在下面的例子中,我們將在Library/caches文件夾下創(chuàng)建名為MyAppCache的目錄。可以這樣創(chuàng)建:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,

NSUserDomainMask, YES);

NSString *cachesDirectory = [paths objectAtIndex:0];

cachesDirectory = [cachesDirectory

stringByAppendingPathComponent:@"MyAppCache"];

把緩存存儲在緩存文件夾下的原因是iCloud(和iTunes)的備份不包括此目錄。如果在Documents目錄下創(chuàng)建了大尺寸的緩存文件,它們會在備份的時候被上傳到iCloud并且很快就用完有限的空間(寫作本書時大約為5 GB)。你不會這么干的——誰不想成為用戶iPhone上的良民?NSCachesDirectory正是解決這個問題的。

預(yù)緩存是用高級數(shù)據(jù)庫(比如原始的SQLite)或者對象序列化框架(比如Core Data)實現(xiàn)的。我們需要根據(jù)需求認(rèn)真選擇不同的技術(shù)。本節(jié)第5點“應(yīng)該用哪種緩存技術(shù)”給出了一些建議:什么時候該用URL緩存或者數(shù)據(jù)模型緩存,而什么時候又該用Core Data。接下來先看一下數(shù)據(jù)模型緩存的實現(xiàn)細(xì)節(jié)。

1. 實現(xiàn)數(shù)據(jù)模型緩存

可以用NSKeyedArchiver類來實現(xiàn)數(shù)據(jù)模型緩存。為了把模型對象用NSKeyedArchiver歸檔,模型類需要遵循NSCoding協(xié)議。

NSCoding協(xié)議方法

- (void)encodeWithCoder:(NSCoder *)aCoder; - (id)initWithCoder:(NSCoder *)aDecoder;

當(dāng)模型遵循NSCoding協(xié)議時,歸檔對象就很簡單,只要調(diào)用下列方法中的一個:

[NSKeyedArchiver archiveRootObject:objectForArchiving

toFile:archiveFilePath];

[NSKeyedArchiver archivedDataWithRootObject:objectForArchiving];

第一個方法在archiveFilePath指定的路徑下創(chuàng)建一個歸檔文件。第二個方法則返回一個NSData對象。NSData通常更快,因為沒有文件訪問開銷,但對象保存在應(yīng)用的內(nèi)存中,如果不定期檢查的話會很快用完內(nèi)存。在iPhone上定期緩存到閃存的功能也是不明智的,因為跟硬盤不同,閃存讀寫壽命是有限的。開發(fā)者得盡可能平衡好兩者的關(guān)系。24.3節(jié)會詳細(xì)介紹歸檔實現(xiàn)緩存。

NSKeyedUnarchiver類用于從文件(或者NSData指針)反歸檔模型。根據(jù)反歸檔的位置,選擇使用下面兩個類方法。

[NSKeyedUnarchiver unarchiveObjectWithData:data];

[NSKeyedUnarchiver unarchiveObjectWithFile:archiveFilePath];

這四個方法在轉(zhuǎn)化序列化數(shù)據(jù)時能派上用場。

使用任何NSKeyedArchiver/NSKeyedUnarchiver的前提是模型實現(xiàn)了NSCoding協(xié)議。不過要做到這一點很容易,可以用Accessorizer類工具自動實現(xiàn)NSCoding協(xié)議。(24.8節(jié)列出了Accessorizer在Mac App Store中的鏈接。)

下一節(jié)會解釋預(yù)緩存策略。我們剛才已經(jīng)了解到預(yù)緩存需要用到更結(jié)構(gòu)化的數(shù)據(jù)格式,接下來看看Core Data和SQLite。

2. Core Data

正如Marcus Zarra所說,Core Data更像是一個對象序列化框架,而不僅僅是一個數(shù)據(jù)庫API:

大家誤認(rèn)為Core

Data是一個Cocoa的數(shù)據(jù)庫API……其實它是個可以持久化到磁盤的對象框架(Zarra,2009年)。

要深入理解Core Data,看一下Marcus S. Zarra寫的*Core Data: Apple's API for Persisting Data on Mac OS X*(Pragmatic Bookshelf, 2009. ISBN 9781934356326)。

要在Core Data中保存數(shù)據(jù),首先創(chuàng)建一個Core Data模型文件,并創(chuàng)建實體(Entity)和關(guān)系(Relationship);然后寫好保存和獲取數(shù)據(jù)的方法。應(yīng)用可以借助Core Data獲取真正的離線訪問功能,就像蘋果內(nèi)置的Mail和Calendar應(yīng)用一樣。實現(xiàn)預(yù)緩存時必須定期刪除不再需要的(過時的)數(shù)據(jù),否則緩存會不斷增長并影響應(yīng)用的性能。同步本地變更是通過追蹤變更集并發(fā)送回服務(wù)器實現(xiàn)的。變更集的追蹤有很多算法,我推薦的是Git版本控制系統(tǒng)所用的(此處沒有涉及如何與遠(yuǎn)程服務(wù)器同步緩存,這不在本書討論范圍之內(nèi))。

3. 用Core Data實現(xiàn)按需緩存

盡管從技術(shù)上講可以用Core Data來實現(xiàn)按需緩存,但我不建議這么做。Core Data的優(yōu)勢是不用反歸檔完整的數(shù)據(jù)就可以獨立訪問模型的屬性。然而,在應(yīng)用中實現(xiàn)Core Data帶來的復(fù)雜度抵消了優(yōu)勢。此外,對于按需緩存實現(xiàn)來說,我們可能并不需要獨立訪問模型的屬性。

4. 原始的SQLite

可以通過鏈接libsqlite3的庫來把SQLite嵌入應(yīng)用,但是這么做有很大的缺陷。所有的sqlite3庫和對象關(guān)系映射(Object Relational Mapping,ORM)機(jī)制幾乎總是會比Core Data慢。此外,盡管sqlite3本身是線程安全的,但是iOS上的二進(jìn)制包則不是。所以除非用定制編譯的sqlite3庫(用線程安全的編譯參數(shù)編譯),否則開發(fā)者就有責(zé)任確保從sqlite3讀取數(shù)據(jù)或者往sqlite3寫入數(shù)據(jù)是線程安全的。Core Data有這么多特性而且內(nèi)置線程安全,所以我建議在iOS中盡量避免使用SQLite。

唯一應(yīng)該在iOS應(yīng)用中用原始的SQLite而不用Core Data的例外情況是,資源包中有應(yīng)用程序相關(guān)的數(shù)據(jù)需要在所有應(yīng)用支持的第三方平臺上共享,比如說運(yùn)行在iPhone、Android、BlackBerry和Windows Phone上的某個應(yīng)用的位置數(shù)據(jù)庫。不過這也不是緩存了。

5. 應(yīng)該用哪種緩存技術(shù)

在眾多可以本地保存數(shù)據(jù)的技術(shù)中,有三種脫穎而出:URL緩存、數(shù)據(jù)模型緩存(利用NSKeyedArchiver)和Core Data。

假設(shè)你正在開發(fā)一個應(yīng)用,需要緩存數(shù)據(jù)以改善應(yīng)用表現(xiàn)出的性能,你應(yīng)該實現(xiàn)按需緩存(使用數(shù)據(jù)模型緩存或URL緩存)。另一方面,如果需要數(shù)據(jù)能夠離線訪問,而且具有合理的存儲方式以便離線編輯,那么就用高級序列化技術(shù)(如Core Data)。

6. 數(shù)據(jù)模型緩存與URL緩存

按需緩存可以用數(shù)據(jù)模型緩存或URL緩存來實現(xiàn)。兩種方式各有優(yōu)缺點,要使用哪一種取決于服務(wù)器的實現(xiàn)。URL緩存的實現(xiàn)原理和瀏覽器緩存或代理服務(wù)器緩存類似。當(dāng)服務(wù)器設(shè)計得體,遵循HTTP 1.1的緩存規(guī)范時,這種緩存效果最好。如果服務(wù)器是SOAP服務(wù)器(或者實現(xiàn)類似于RPC服務(wù)器或RESTful服務(wù)器),就需要用數(shù)據(jù)模型緩存。如果服務(wù)器遵循HTTP 1.1緩存規(guī)范,就用URL緩存。數(shù)據(jù)模型緩存允許客戶端(iOS應(yīng)用)掌控緩存失效的情形,當(dāng)開發(fā)者實現(xiàn)URL緩存時,服務(wù)器通過HTTP 1.1的緩存控制頭控制緩存失效。盡管有些程序員覺得這種方式違反直覺,而且實現(xiàn)起來也很復(fù)雜(尤其是在服務(wù)器端),但這可能是實現(xiàn)緩存的好辦法。事實上,MKNetworkKit提供了對HTTP 1.1緩存標(biāo)準(zhǔn)的原生支持。

數(shù)據(jù)模型緩存:

本節(jié)我們來給第14章中的iHotelApp添加用數(shù)據(jù)模型緩存實現(xiàn)的按需緩存。按需緩存是在視圖從視圖層次結(jié)構(gòu)中消失時做的(從技術(shù)上講,是在viewWillDisappear:方法中)。支持緩存的視圖控制器的基本結(jié)構(gòu)如圖24-1所示。AppCache Architecture的完整代碼可從本章的下載源代碼中找到。后面講解的內(nèi)容假設(shè)你已經(jīng)下載了代碼并且可以隨時使用。

名單

圖24-1

實現(xiàn)了按需緩存的視圖控制器的控制流

在viewWillAppear方法中,查看緩存中是否有顯示這個視圖所需的數(shù)據(jù)。如果有就獲取數(shù)據(jù),再用緩存數(shù)據(jù)更新用戶界面。然后檢查緩存中的數(shù)據(jù)是否已經(jīng)過期。你的業(yè)務(wù)規(guī)則應(yīng)該能夠確定什么是新數(shù)據(jù)、什么是舊數(shù)據(jù)。如果內(nèi)容是舊的,把數(shù)據(jù)顯示在UI上,同時在后臺從服務(wù)器獲取數(shù)據(jù)并再次更新UI。如果緩存中沒有數(shù)據(jù),顯示一個轉(zhuǎn)動的圓圈表示正在加載,同時從服務(wù)器獲取數(shù)據(jù)。得到數(shù)據(jù)后,更新UI。

前面的流程圖假定顯示在UI上的數(shù)據(jù)是可以歸檔的模型。在iHotelApp的MenuItem模型中實現(xiàn)NSCoding協(xié)議。NSKeyedArchiver需要模型實現(xiàn)這個協(xié)議,如下面的代碼片段所示。

MenuItem類的encodeWithCoder方法(MenuItem.m)

- (void)encodeWithCoder:(NSCoder *)encoder

{

[encoder encodeObject:self.itemId forKey:@"ItemId"];

[encoder encodeObject:self.image forKey:@"Image"];

[encoder encodeObject:self.name forKey:@"Name"];

[encoder encodeObject:self.spicyLevel forKey:@"SpicyLevel"];

[encoder encodeObject:self.rating forKey:@"Rating"];

[encoder encodeObject:self.itemDescription forKey:@"ItemDescription"];

[encoder encodeObject:self.waitingTime forKey:@"WaitingTime"];

[encoder encodeObject:self.reviewCount forKey:@"ReviewCount"];

}

MenuItem類的initWithCoder方法(MenuItem.m)

- (id)initWithCoder:(NSCoder *)decoder

{if ((self = [super init])) {

self.itemId = [decoder decodeObjectForKey:@"ItemId"];

self.image = [decoder decodeObjectForKey:@"Image"];

self.name = [decoder decodeObjectForKey:@"Name"];

self.spicyLevel = [decoder decodeObjectForKey:@"SpicyLevel"];

self.rating = [decoder decodeObjectForKey:@"Rating"];

self.itemDescription = [decoder

decodeObjectForKey:@"ItemDescription"];

self.waitingTime = [decoder decodeObjectForKey:@"WaitingTime"];

self.reviewCount = [decoder decodeObjectForKey:@"ReviewCount"];

}return self;

}

就像之前提到過的,可以用Accessorizer來生成NSCoding協(xié)議的實現(xiàn)。

根據(jù)圖24-1中的緩存流程圖,我們需要在viewWillAppear:中實現(xiàn)實際的緩存邏輯。把下面的代碼加入viewWillAppear:就可以實現(xiàn)。

視圖控制器的viewWillAppear:方法中從緩存恢復(fù)數(shù)據(jù)模型對象的代碼片段

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,

NSUserDomainMask, YES);

NSString *cachesDirectory = [paths objectAtIndex:0];

NSString *archivePath = [cachesDirectory

stringByAppendingPathComponent:@"AppCache/MenuItems.archive"];

NSMutableArray *cachedItems = [NSKeyedUnarchiver

unarchiveObjectWithFile:archivePath];if(cachedItems == nil)

self.menuItems = [AppDelegate.engine localMenuItems];else

self.menuItems = cachedItems;

NSTimeInterval stalenessLevel = [[[[NSFileManager defaultManager]

attributesOfItemAtPath:archivePath error:nil]

fileModificationDate] timeIntervalSinceNow];if(stalenessLevel > THRESHOLD)

self.menuItems = [AppDelegate.engine localMenuItems];

[self updateUI];

緩存機(jī)制的邏輯流如下所示。

視圖控制器在歸檔文件MenuItems.archive中檢查之前緩存的項并反歸檔。

如果MenuItems.archive不存在,視圖控制器調(diào)用方法從服務(wù)器獲取數(shù)據(jù)。

如果MenuItems.archive存在,視圖控制器檢查歸檔文件的修改時間以確認(rèn)緩存數(shù)據(jù)有多舊。如果數(shù)據(jù)過期了(由業(yè)務(wù)需求決定),再從服務(wù)器獲取一次數(shù)據(jù)。否則顯示緩存的數(shù)據(jù)。

接下來,把下面的代碼加入viewDidDisappear方法可以把模型(以NSKeyedArchiver的形式)保存在Library/Caches目錄中。

視圖控制器的viewWillDisappear:方法中緩存數(shù)據(jù)模型的代碼片段

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,

NSUserDomainMask, YES);

NSString *cachesDirectory = [paths objectAtIndex:0];

NSString *archivePath = [cachesDirectory stringByAppendingPathComponent:@" AppCache/MenuItems.archive"];

[NSKeyedArchiver archiveRootObject:self.menuItems toFile:archivePath];

視圖消失時要把menuItems數(shù)組的內(nèi)容保存在歸檔文件中。注意,如果不是在viewWillAppear:方法中從服務(wù)器獲取數(shù)據(jù)的話,這種情況不能緩存。

所以,只需在視圖控制器中加入不到10行的代碼(并將Accessorizer生成的幾行代碼加入模型),就可以為應(yīng)用添加緩存支持了。

重構(gòu)

當(dāng)開發(fā)者有多個視圖控制器時,前面的代碼可能會有冗余。我們可以通過抽象出公共代碼并移入名為AppCache的新類來避免冗余。AppCache是處理緩存的應(yīng)用的核心。把公共代碼抽象出來放入AppCache可以避免viewWillAppear:和viewWillDisappear:中出現(xiàn)冗余代碼。

重構(gòu)這部分代碼,使得視圖控制器的viewWillAppear/viewWillDisappear代碼塊看起來如下所示。加粗部分顯示重構(gòu)時所做的修改,我會在代碼后面解釋。

視圖控制器的viewWillAppear:方法中用AppCache類緩存數(shù)據(jù)模型的重構(gòu)代碼片段(MenuItemsViewController.m)

-(void) viewWillAppear:(BOOL)animated {

self.menuItems = [AppCache getCachedMenuItems];

[self.tableView reloadData];if([AppCache isMenuItemsStale] || !self.menuItems) {

[AppDelegate.engine fetchMenuItemsOnSucceeded:^(NSMutableArray *listOfModelBaseObjects) {

self.menuItems = listOfModelBaseObjects;

[self.tableView reloadData];

} onError:^(NSError *engineError) {

[UIAlertView showWithError:engineError];

}];

}

[super viewWillAppear:animated];

} -(void) viewWillDisappear:(BOOL)animated {

[AppCache cacheMenuItems:self.menuItems];

[super viewWillDisappear:animated];

}

AppCache類把判斷數(shù)據(jù)是否過期的邏輯從視圖控制器中抽象出來了,還把緩存保存的位置也抽象出來了。稍后在本章中我們還會修改AppCache,再引入一層緩存,內(nèi)容會保存在內(nèi)存中。

因為AppCache抽象出了緩存的保存位置,我們就不需要為復(fù)制粘貼代碼來獲得應(yīng)用的緩存目錄而操心了。如果應(yīng)用類似于iHotelApp,開發(fā)者可通過為每個用戶創(chuàng)建子目錄即可輕松增強(qiáng)緩存數(shù)據(jù)的安全性。然后我們就可以修改AppCache中的輔助方法,現(xiàn)在它返回的是緩存目錄,我們可以讓它返回當(dāng)前登錄用戶的子目錄。這樣,一個用戶緩存的數(shù)據(jù)就不會被隨后登錄的用戶看到了。

完整的代碼可以從本書網(wǎng)站上本章的源代碼下載中獲取。

緩存版本控制:

我們在上一節(jié)中寫的AppCache類從視圖控制器中抽象出了按需緩存。當(dāng)視圖出現(xiàn)和消失時,緩存就在幕后工作。然而,當(dāng)你更新應(yīng)用時,模型類可能會發(fā)生變化,這意味著之前歸檔的任何數(shù)據(jù)將不能恢復(fù)到新的模型上。正如之前所講,對按需緩存來說,數(shù)據(jù)并沒有那么重要,開發(fā)者可以刪除數(shù)據(jù)并更新應(yīng)用。我會展示可以用來在版本升級時刪除緩存目錄的代碼片段。

iOS中驗證模型:

第二個是驗證模型,服務(wù)器通常會發(fā)送一個校驗和(Etag)。后續(xù)所有從緩存獲得資源的請求都應(yīng)該用這個校驗和向服務(wù)器**重新驗證**資源是否有變化。如果校驗和匹配,服務(wù)器就返回一個HTTP 304 Not Modified的狀態(tài)碼。

IOS內(nèi)存緩存:

目前為止,所有iOS設(shè)備都帶有閃存,而閃存有點小問題:它的讀寫壽命是有限的。盡管這個壽命跟設(shè)備的使用壽命比起來很長,但是仍然需要避免過于頻繁地讀寫閃存。在上一個例子中,視圖隱藏時是直接緩存到磁盤的,而視圖顯示時又是直接從磁盤讀取的。這種行為會使用戶設(shè)備的緩存負(fù)擔(dān)很重。為避免這個問題,我們可以再引入一層緩存,利用設(shè)備的RAM而不是閃存(用NSMutableDictionary)。在24.2.1節(jié)的“實現(xiàn)數(shù)據(jù)模型緩存”中,我們介紹了創(chuàng)建歸檔的兩種方法:一個是保存到文件,另一個是保存為NSData對象。這次會用到第二個方法,我們會得到一個NSData指針,將該指針保存到NSMutableDictionary中,而不是文件系統(tǒng)里的平面文件。引入內(nèi)存緩存的另一個好處是,在歸檔和反歸檔內(nèi)容時性能會略有提升。聽起來很復(fù)雜,實際上并不復(fù)雜。本節(jié)將介紹如何給AppCache類添加一層透明的、位于內(nèi)存中的緩存。(“透明”是指調(diào)用代碼,即視圖控制器,甚至不知道這層緩存的存在,而且也不需要改動任何代碼。)我們還會設(shè)計一個LRU(Least Recently Used,最近最少使用)算法來把緩存的數(shù)據(jù)保存到磁盤。

以下簡單列出了要創(chuàng)建內(nèi)存緩存需要的步驟。這些步驟將會在下面幾節(jié)中詳細(xì)解釋。

添加變量來存放內(nèi)存緩存數(shù)據(jù)。

限制內(nèi)存緩存大小,并且把最近最少使用的項寫入文件,然后從內(nèi)存緩存中刪除。RAM是有限的,達(dá)到使用極限就會觸發(fā)內(nèi)存警告。收到警告時不釋放內(nèi)存會使應(yīng)用崩潰。我們當(dāng)然不希望發(fā)生這種事,所以要為內(nèi)存緩存設(shè)置一個最大閾值。當(dāng)緩存滿了以后再添加任何東西時,最近最少使用的對象應(yīng)該被保存到文件(閃存中)。

處理內(nèi)存警告,并把內(nèi)存緩存以文件形式寫入閃存。

當(dāng)應(yīng)用關(guān)閉、退出,或進(jìn)入后臺時,把內(nèi)存緩存全部以文件形式寫入閃存。

更多信息請查看IT技術(shù)專欄

更多信息請查看技術(shù)文章
易賢網(wǎng)手機(jī)網(wǎng)站地址:IOS緩存機(jī)制詳解
由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢回復(fù)僅供參考,敬請考生以權(quán)威部門公布的正式信息和咨詢?yōu)闇?zhǔn)!
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機(jī)站點

版權(quán)所有:易賢網(wǎng)

亚洲免费不卡_在线视频精品_国产尤物精品_久久久久网址_久久精品91_欧美va天堂在线_狠狠入ady亚洲精品_亚洲午夜精品福利_国产精品草草_午夜精品久久99蜜桃的功能介绍
香蕉成人久久| 欧美日韩一区二区三区在线视频 | 久久大逼视频| 男人的天堂成人在线| 国产精品三区www17con| 在线亚洲免费| 欧美精品日韩| 国产精品试看| 欧美1区2区3区| 亚洲日本视频| 久久蜜桃精品| 亚洲国产1区| 久久伊人亚洲| 亚洲国产一区二区精品专区| 亚洲一区二区成人| 18成人免费观看视频| 99精品国产99久久久久久福利| 久久精品天堂| 在线观看日韩av电影| 国产亚洲一区二区三区在线播放| 欧美1区免费| 亚洲伦理一区| 欧美全黄视频| 国产精品一区在线播放| 国产主播一区| 久久久噜噜噜| 一本色道久久综合| 欧美精品成人| 麻豆久久久9性大片| 激情婷婷久久| 欧美日韩精品综合| 亚洲中字在线| 亚洲免费不卡| 在线观看视频日韩| 欧美精品一线| 欧美精品1区| 欧美在线网站| 欧美黄色一区| 欧美福利视频| 欧美成人在线免费观看| 久久亚洲图片| 欧美在线视屏| 欧美激情第六页| 欧美在线不卡| 欧美日韩精品免费观看视一区二区 | 久久都是精品| 羞羞答答国产精品www一本| 国产私拍一区| 先锋影音久久久| 香蕉视频成人在线观看| 亚洲欧美日韩国产一区二区| 国产伦精品一区二区三区四区免费 | 噜噜噜久久亚洲精品国产品小说| 日韩亚洲在线| 国产欧美一级| 亚洲一区网站| 久久久久久九九九九| 米奇777在线欧美播放| 久久国产精品毛片| 欧美区高清在线| 一区免费在线| 亚洲精品乱码| 亚洲在线黄色| 欧美日韩精品免费观看| 欧美日韩精品不卡| 99热精品在线观看| 久久资源av| 亚洲国产精品第一区二区| 亚洲成色www久久网站| 正在播放亚洲| 欧美久久久久久久| 亚洲美洲欧洲综合国产一区| 国产精品一区二区三区免费观看| 蜜乳av另类精品一区二区| 欧美日韩三区| 宅男噜噜噜66国产日韩在线观看| 免费在线成人av| 伊人久久婷婷色综合98网| 国产精品视频免费观看| 欧美日韩在线高清| 性感少妇一区| 亚洲成色www久久网站| 亚洲自拍另类| 影音先锋在线一区| 欧美成人一区二免费视频软件| 亚洲午夜精品一区二区| 亚洲专区一区| 在线视频观看日韩| 欧美成人有码| 麻豆久久婷婷| 日韩亚洲视频在线| 国产自产在线视频一区| 老司机一区二区三区| 在线成人h网| 可以免费看不卡的av网站| 99在线精品视频在线观看| 欧美成人中文| 久久久精品动漫| 国产精品久久久久久久久久直播| 亚洲一本视频| 国内精品福利| 欧美成人嫩草网站| 久久免费99精品久久久久久| 国产精品丝袜xxxxxxx| 尤物在线精品| 国模大胆一区二区三区| 欧美国产日本| 亚洲一区激情| 亚洲欧美国产不卡| 国产精品一卡| 在线天堂一区av电影| 在线观看成人一级片| 国内精品久久久久久久果冻传媒| 久久综合九色99| 久久精品日产第一区二区 | 9国产精品视频| 激情综合自拍| 亚洲一二区在线| 黄色av一区| 欧美特黄一级| 国产精品久久久久久久久久妞妞| 亚洲一区二区免费看| 亚洲午夜电影| 噜噜噜躁狠狠躁狠狠精品视频| 日韩视频在线播放 | 欧美三级网页| 欧美日韩一区二区三区在线视频 | 精品1区2区| 激情一区二区三区| 亚洲高清激情| 亚洲国产免费看| 麻豆成人av| 国产日韩欧美高清免费| 国模精品一区二区三区| 中文欧美日韩| 亚洲日本精品国产第一区| 亚洲人成久久| 国产精品毛片va一区二区三区| 日韩午夜高潮| 麻豆亚洲精品| 国产精品草草| 最新成人av网站| 先锋影音久久久| 欧美日韩亚洲三区| 99www免费人成精品| 乱人伦精品视频在线观看| 午夜精品一区二区三区四区 | 99精品视频免费观看视频| 国产精品嫩草99av在线| 久久精品女人的天堂av| 欧美日韩一区二区三区四区在线观看 | 久久久一本精品99久久精品66| 欧美/亚洲一区| 亚洲精品1区| 久久九九精品| 亚洲人成毛片在线播放女女| 亚洲欧美激情诱惑| 亚洲黑丝一区二区| 欧美.www| 小嫩嫩精品导航| 亚洲福利精品| 欧美成人精品| 国产日韩一区二区三区| 欧美日韩国产三区| 性一交一乱一区二区洋洋av| 激情欧美国产欧美| 欧美成人dvd在线视频| 国产亚洲欧美一区二区| 精品9999| 国产综合激情| 欧美大片专区| 久久婷婷丁香| 久久国产精品久久精品国产| 亚洲久久一区二区| 亚洲一级一区| 国内成+人亚洲| 欧美精品自拍| 老牛嫩草一区二区三区日本 | 激情欧美日韩一区| 亚洲欧美一级二级三级| 亚洲欧美视频| 亚洲一区二区精品在线观看| 亚洲精品婷婷| 亚洲理论在线| 夜夜嗨av一区二区三区网站四季av| 欧美日韩亚洲一区在线观看| 久久综合狠狠| 午夜精彩国产免费不卡不顿大片| 亚洲欧美日韩视频二区| 国产一区二区高清视频| 99精品免费视频| 亚洲精选在线| 亚洲麻豆av| 国产一区二区你懂的| 国产欧美韩日| 亚洲视频1区| 久久av免费一区| 久久青青草原一区二区| 欧美69视频| 欧美日韩影院| 亚洲天堂黄色| 日韩亚洲国产精品| 亚洲欧美日韩综合一区| 欧美在线网站| 国产一区在线免费观看| 韩国欧美一区| 亚洲美女一区| 久久国产66| 国产自产在线视频一区| 亚洲精品欧洲精品| 国产一区二区三区免费不卡| 羞羞视频在线观看欧美| 女同一区二区| 136国产福利精品导航网址| 日韩视频不卡| 久久九九电影| 在线 亚洲欧美在线综合一区| 亚洲激情亚洲| 久久久久国内| 在线成人h网| 久久成人资源| 在线精品福利| 嫩草成人www欧美| 亚洲天堂偷拍| 免费在线成人av| 狠狠色伊人亚洲综合网站色| 夜久久久久久| 欧美777四色影| 在线视频精品一区| 欧美在线二区| 国产视频久久| 红桃视频国产一区| 亚洲欧美国产精品桃花| 精品99视频| 久久久久九九九| 一区二区三区精品视频在线观看| 欧美+日本+国产+在线a∨观看| 亚洲黄色毛片| 欧美私人啪啪vps| 久久精品官网| 中文久久精品| 亚洲三级影院| 亚洲第一在线| 欧美精品午夜| 欧美一区二区三区四区夜夜大片| 中文久久精品| 亚洲激情啪啪| 激情一区二区三区| 欧美激情精品久久久六区热门| 夜夜嗨网站十八久久| 好吊日精品视频| 久久在线精品| 久久riav二区三区| 在线亚洲自拍| 亚洲精品激情| 亚洲黄色成人| 亚洲精品乱码久久久久久蜜桃麻豆 | 久久精品女人天堂| 国产精品乱子乱xxxx| 亚洲国产精品www| 极品av少妇一区二区| 欧美日韩少妇| 欧美日韩在线高清| 欧美日韩成人一区二区三区| 女主播福利一区| 欧美精品国产| 欧美午夜a级限制福利片| 欧美日本二区| 国产一区二区无遮挡| 欧美三级在线| 国产主播一区二区三区四区| 国产精品www994| 精品91久久久久| 激情欧美一区二区三区| 激情自拍一区| 亚洲日韩视频| 国产精品视频免费观看| 国产精品一区二区三区免费观看| 亚洲三级色网| 国产日本精品| 午夜一区二区三区不卡视频| 久久狠狠久久综合桃花| 久久一区中文字幕| 欧美日韩天天操| 亚洲第一网站| 夜夜爽99久久国产综合精品女不卡| 99在线精品免费视频九九视| 国产精品乱看| 欧美福利一区| 在线国产日韩| 亚洲中午字幕| 欧美精品一级| 亚洲每日更新| 久久久久.com| 亚洲国产导航| 美女网站久久| 国产综合婷婷| 亚洲一区日韩| 欧美日韩三区四区| 国产日韩欧美一区| 久久婷婷麻豆| 在线观看一区视频| 亚洲欧美日韩国产| 欧美日本韩国一区二区三区| 亚洲三级影院| 欧美黄色一区二区| 国产精品美女xx| 久热这里只精品99re8久| 一区视频在线看| 美女黄色成人网| 亚洲电影成人| 欧美日本一区二区高清播放视频| 一本久道综合久久精品| 亚洲欧美文学| 免费在线亚洲欧美| 日韩一区二区久久| 国产精品国产三级欧美二区| 亚洲一区二区伦理| 亚洲国产综合在线看不卡| 久久国产精品一区二区三区| 伊人精品成人久久综合软件| 久久综合九色综合网站| 亚洲一区二区在线免费观看| 亚洲国产99| 黑人一区二区| 欧美日韩一区二区三| 久久久久国产精品一区三寸| 一区二区免费在线视频| 伊人久久婷婷色综合98网| 欧美精品七区| 欧美精品国产一区二区| 久久久噜噜噜久久狠狠50岁| 国产欧美在线| 99pao成人国产永久免费视频| 国产综合婷婷| 国产尤物精品| 狠狠88综合久久久久综合网| 午夜欧美精品久久久久久久| 国产日韩欧美二区| av不卡在线看| 国产日韩免费| 夜夜嗨一区二区三区| 亚洲精品一级| aa亚洲婷婷| 国产伦精品一区二区三区四区免费| 亚洲精品在线观看免费| 亚洲毛片网站| 国产九区一区在线| 午夜亚洲福利在线老司机| 国产精品制服诱惑| 免费日韩精品中文字幕视频在线| 国产女主播一区二区| 免费不卡亚洲欧美| 欧美一区二区三区在线免费观看| 久久天堂国产精品| 欧美日韩在线高清| 亚洲午夜极品| 99国产精品| 久久精品主播| 亚洲视频一区| 国产手机视频一区二区| 久久九九免费| 亚洲无线一线二线三线区别av| 好看的av在线不卡观看| 日韩亚洲欧美精品| 久久久777| 影音先锋在线一区| 亚洲专区欧美专区| 午夜久久一区| 日韩午夜激情| 欧美一区国产一区| 亚洲丰满在线| 久久久久久久高潮| 亚洲成人原创| 久久福利精品| 亚洲欧洲综合| 欧美暴力喷水在线| 一本综合久久| 欧美日韩综合| 先锋影音久久久| 亚洲福利免费| 牛夜精品久久久久久久99黑人| 激情综合亚洲| 蜜桃av久久久亚洲精品| 一区在线播放| 合欧美一区二区三区| 欧美在线国产| 一区二区三区免费看| 欧美日韩精品一本二本三本| 99pao成人国产永久免费视频| 久久婷婷人人澡人人喊人人爽| 一区二区亚洲| 久久综合中文色婷婷| 一区二区三区视频在线播放| 欧美大片专区| 亚洲综合国产| 99国产精品久久久久老师| 欧美色一级片| 久久久人人人| 亚洲一区二区四区|