?在手機(jī)應(yīng)用程序開發(fā)中,為了降低與服務(wù)端的交互次數(shù),加快用戶的響應(yīng)速度,一般都會(huì)在iOS設(shè)備中加一個(gè)緩存的機(jī)制,前面一篇文章介紹了iOS設(shè)備的內(nèi)存緩存。這篇文章將設(shè)計(jì)一個(gè)本地緩存的機(jī)制。
功能需求
這個(gè)緩存機(jī)制滿足以下這些功能。
1、能夠?qū)?shù)據(jù)緩存到本地磁盤。
2、能夠推斷一個(gè)資源是否已經(jīng)被緩存。假設(shè)已經(jīng)被緩存。在請求同樣的資源。先到本地磁盤搜索。
3、能夠推斷文件緩存什么時(shí)候過期。這里為了簡單起見這里,我們在請求url資源的時(shí)候。給每次請求的文件設(shè)定一個(gè)過期的時(shí)間。
4、能夠?qū)崿F(xiàn):假設(shè)文件已經(jīng)被緩存,并且沒有過期。這將本地的數(shù)據(jù)返回,否則又一次請求url。
5、能夠?qū)崿F(xiàn):假設(shè)文件下載不成功或者下載沒有完畢,下次打開程序的時(shí)候,移除這些沒有成功或者沒有下載完畢的文件。
6、能夠?qū)崿F(xiàn):同一時(shí)候請求或者下載多個(gè)資源。
設(shè)計(jì)實(shí)現(xiàn):
1、設(shè)計(jì)一個(gè)CacheItem類,用來請求一個(gè)web連接,它的一個(gè)實(shí)例表示一個(gè)緩存項(xiàng)。
這個(gè)CacheItem類,須要一個(gè)url創(chuàng)建一個(gè)NSURLConnection,去請求web資源。
使用CacheItem類主要用來請求web資源。
[plain]?view plaincopy
/*?---------緩存項(xiàng)--------------?*/?? ?? @interface?CacheItem?:?NSObject?{?? @public?? ??id<CacheItemDelegate>?delegate;?? ????//web地址?? ??NSString??????????????*remoteURL;?? @private?? ????//是否正在下載?? ??BOOL??????????????????isDownloading;?? ???????//NSMutableData對象?? ??NSMutableData?????????*connectionData;?? ????//NSURLConnection對象?? ??NSURLConnection???????*connection;?? }?? ?? /*?--------------------------?*/?? ?? @property?(nonatomic,?retain)?id<CacheItemDelegate>?delegate;?? @property?(nonatomic,?retain)?NSString??*remoteURL;?? @property?(nonatomic,?assign)?BOOL??????isDownloading;?? @property?(nonatomic,?retain)?NSMutableData?*connectionData;?? @property?(nonatomic,?retain)?NSURLConnection?*connection;?? ?? /*?----------開始下載方法-----------?*/?? ?? -?(BOOL)?startDownloadingURL:(NSString?*)paramRemoteURL;?? ?? @end?? 2、在NSURLConnection開始請求之前,調(diào)用CachedDownloadManager類,來搜索和管理本地的緩存文件。將緩存文件的情況保存到一個(gè)字典類中。
這個(gè)字典設(shè)計(jì)例如以下:
[plain]?view plaincopy
{?? ??"http://www.cnn.com"?=?????{?? ????DownloadEndDate?=?"2011-08-02?07:51:57?+0100";?? ????DownloadStartDate?=?"2011-08-02?07:51:55?+0100";?? ????ExpiresInSeconds?=?20;?? ????ExpiryDate?=?"2011-08-02?07:52:17?+0100";?? ????LocalURL?=?"/var/mobile/Applications/ApplicationID/Documents/?? ????????????????httpwww.cnn.com.cache";?? ??};?? ??"http://www.baidu.com"?=?????{?? ????DownloadEndDate?=?"2011-08-02?07:51:49?+0100";?? ????DownloadStartDate?=?"2011-08-02?07:51:44?+0100";?? ????ExpiresInSeconds?=?20;?? ????ExpiryDate?=?"2011-08-02?07:52:09?+0100";?? ????LocalURL?=?"/var/mobile/Applications/ApplicationID/Documents/?? ????????????????httpwww.oreilly.com.cache";?? ??};?? }?? ?上面這個(gè)字典里面嵌套了字典。里面那層字典表示一個(gè)緩存項(xiàng)的緩存信息:下載結(jié)束時(shí)間、下載開始時(shí)間、緩存有效時(shí)間、緩存過期時(shí)間、緩存到本地的路徑。
?? 以下看下CachedDownloadManager類。
用它來實(shí)現(xiàn)和封裝我們的緩存策略。?
?
[plain]?view plaincopy
/*?-----------CachedDownloadManager--------------?*/?? ?? @interface?CachedDownloadManager?:?NSObject??? ???????????????????????????????????<CacheItemDelegate>?{?? @public?? ??id<CachedDownloadManagerDelegate>??delegate;?? @private?? //記錄緩存數(shù)據(jù)的字典?? ??NSMutableDictionary????????????????*cacheDictionary;?? ???????????????????????????????????????//緩存的路徑?? ??NSString???????????????????????????*cacheDictionaryPath;?? }?? ?? ?? @property?(nonatomic,?assign)??? id<CachedDownloadManagerDelegate>?delegate;?? ?? @property?(nonatomic,?copy)??? NSMutableDictionary?*cacheDictionary;?? ?? @property?(nonatomic,?retain)??? NSString?*cacheDictionaryPath;?? ?? ?? /*?保持緩存字典?*/?? ?? -?(BOOL)?saveCacheDictionary;?? ?? /*?公有方法:下載?*/?? ?? -?(BOOL)?????????download:(NSString?*)paramURLAsString?? ???urlMustExpireInSeconds:(NSTimeInterval)paramURLMustExpireInSeconds?? updateExpiryDateIfInCache:(BOOL)paramUpdateExpiryDateIfInCache;?? ?? /*?--------------------------?*/?? ?? @end?? ?
?? 從上面代碼能夠看出,這個(gè)管理緩存的類中。有一個(gè)緩存字典:cacheDictionary,用來表示全部資源的緩存情況;cacheDictionaryPath用來表示緩存的路徑。saveCacheDictionary用來將緩存字典歸檔到本地文件里。
download:urlMustExpireInSeconds:updateExpiryDateIfInCache是一個(gè)公共接口,通過傳遞url、緩存過期時(shí)間、是否更新緩存過期時(shí)間三個(gè)參數(shù)來方便的使用,實(shí)現(xiàn)我們的緩存策略。
3、假設(shè)這個(gè)文件已經(jīng)被下載,并且沒有過期。則從本地獲取文件的數(shù)據(jù)。假設(shè)文件已經(jīng)過期。則又一次下載。
我們通過download:urlMustExpireInSeconds:updateExpiryDateIfInCache方法來實(shí)現(xiàn),主要看這種方法的代碼:
[plain]?view plaincopy
/*?---------下載--------------?*/?? ?? -?(BOOL)?????????download:(NSString?*)paramURLAsString?? ???urlMustExpireInSeconds:(NSTimeInterval)paramURLMustExpireInSeconds?? updateExpiryDateIfInCache:(BOOL)paramUpdateExpiryDateIfInCache{?? ???? ??BOOL?result?=?NO;?? ???? ??if?(self.cacheDictionary?==?nil?||?? ??????[paramURLAsString?length]?==?0){?? ????return(NO);?? ??}?? ???? ??paramURLAsString?=?[paramURLAsString?lowercaseString];?? ??//依據(jù)url。從字典中獲取緩存項(xiàng)的相關(guān)數(shù)據(jù)?? ??NSMutableDictionary?*itemDictionary?=??? ??[self.cacheDictionary?objectForKey:paramURLAsString];?? ???? ??/*?使用以下這些變量幫助我們理解緩存邏輯?*/?? ????//文件是否已經(jīng)被緩存?? ??BOOL????fileHasBeenCached?=?NO;?? ????//緩存是否過期?? ??BOOL????cachedFileHasExpired?=?NO;?? ????//緩存文件是否存在?? ??BOOL????cachedFileExists?=?NO;?? ????//緩存文件是否能被載入?? ??BOOL????cachedFileDataCanBeLoaded?=?NO;?? ????//緩存文件數(shù)據(jù)?? ??NSData??*cachedFileData?=?nil;?? ????//緩存文件是否全然下載?? ??BOOL????cachedFileIsFullyDownloaded?=?NO;?? ????//緩存文件是否已經(jīng)下載?? ??BOOL????cachedFileIsBeingDownloaded?=?NO;?? ??//過期時(shí)間?? ??NSDate????*expiryDate?=?nil;?? ????//下載結(jié)束時(shí)間?? ??NSDate????*downloadEndDate?=?nil;?? ????//下載開始時(shí)間?? ??NSDate????*downloadStartDate?=?nil;?? ????//本地緩存路徑?? ??NSString??*localURL?=?nil;?? ????//有效時(shí)間?? ??NSNumber??*expiresInSeconds?=?nil;?? ??NSDate????*now?=?[NSDate?date];?? ???? ??if?(itemDictionary?!=?nil){?? ????fileHasBeenCached?=?YES;?? ??}?? ??//假設(shè)文件已經(jīng)被緩存。則從緩存項(xiàng)相關(guān)數(shù)據(jù)中獲取相關(guān)的值?? ??if?(fileHasBeenCached?==?YES){?? ?????? ????expiryDate?=?[itemDictionary??? ??????????????????objectForKey:CachedKeyExpiryDate];?? ?????? ????downloadEndDate?=?[itemDictionary?? ???????????????????????objectForKey:CachedKeyDownloadEndDate];?? ?????? ????downloadStartDate?=?[itemDictionary?? ?????????????????????????objectForKey:CachedKeyDownloadStartDate];?? ?????? ????localURL?=?[itemDictionary?? ????????????????objectForKey:CachedKeyLocalURL];?? ?????? ????expiresInSeconds?=?[itemDictionary?? ????????????????????????objectForKey:CachedKeyExpiresInSeconds];?? ????//假設(shè)下載開始和結(jié)束時(shí)間不為空,表示文件所有被下載?? ????if?(downloadEndDate?!=?nil?&&??? ????????downloadStartDate?!=?nil){?? ??????cachedFileIsFullyDownloaded?=?YES;?? ????}?? ?????? ????/*?假設(shè)expiresInSeconds不為空。downloadEndDate為空。表示文件已經(jīng)正在下載?*/?? ????if?(expiresInSeconds?!=?nil?&&?? ????????downloadEndDate?==?nil){?? ??????cachedFileIsBeingDownloaded?=?YES;?? ????}?? ?????? ????/*?推斷緩存是否過期?*/?? ????if?(expiryDate?!=?nil?&&?? ????????[now?timeIntervalSinceDate:expiryDate]?>?0.0){?? ??????cachedFileHasExpired?=?YES;?? ????}?? ?????? ????if?(cachedFileHasExpired?==?NO){?? ??????/*?假設(shè)緩存文件沒有過期,載入緩存文件,而且更新過期時(shí)間?*/?? ??????NSFileManager?*fileManager?=?[[NSFileManager?alloc]?init];?? ???????? ??????if?([fileManager?fileExistsAtPath:localURL]?==?YES){?? ????????cachedFileExists?=?YES;?? ????????cachedFileData?=?[NSData?dataWithContentsOfFile:localURL];?? ????????if?(cachedFileData?!=?nil){?? ??????????cachedFileDataCanBeLoaded?=?YES;?? ????????}?/*?if?(cachedFileData?!=?nil){?*/?? ??????}?/*?if?([fileManager?fileExistsAtPath:localURL]?==?YES){?*/?? ???????? ??????[fileManager?release];?? ???????? ??????/*?更新緩存時(shí)間?*/?? ???????? ??????if?(paramUpdateExpiryDateIfInCache?==?YES){?? ?????????? ????????NSDate?*newExpiryDate?=??? ????????[NSDate?dateWithTimeIntervalSinceNow:?? ?????????paramURLMustExpireInSeconds];?? ?????????? ????????NSLog(@"Updating?the?expiry?date?from?%@?to?%@.",??? ??????????????expiryDate,??? ??????????????newExpiryDate);?? ?????????? ????????[itemDictionary?setObject:newExpiryDate?? ???????????????????????????forKey:CachedKeyExpiryDate];?? ?????????? ????????NSNumber?*expires?=??? ????????[NSNumber?numberWithFloat:paramURLMustExpireInSeconds];?? ?????????? ????????[itemDictionary?setObject:expires?? ???????????????????????????forKey:CachedKeyExpiresInSeconds];?? ??????}?? ???????? ????}?/*?if?(cachedFileHasExpired?==?NO){?*/?? ?????? ??}?? ???? ??if?(cachedFileIsBeingDownloaded?==?YES){?? ????NSLog(@"這個(gè)文件已經(jīng)正在下載...");?? ????return(YES);?? ??}?? ???? ??if?(fileHasBeenCached?==?YES){?? ?????? ????if?(cachedFileHasExpired?==?NO?&&?? ????????cachedFileExists?==?YES?&&?? ????????cachedFileDataCanBeLoaded?==?YES?&&?? ????????[cachedFileData?length]?>?0?&&?? ????????cachedFileIsFullyDownloaded?==?YES){?? ???????? ??????/*?假設(shè)文件有緩存并且沒有過期?*/?? ???????? ??????NSLog(@"文件有緩存并且沒有過期.");?? ???????? ??????[self.delegate??? ???????cachedDownloadManagerSucceeded:self?? ???????remoteURL:[NSURL?URLWithString:paramURLAsString]?? ???????localURL:[NSURL?URLWithString:localURL]?? ???????aboutToBeReleasedData:cachedFileData?? ???????isCachedData:YES];?? ???????? ??????return(YES);?? ???????? ????}?else?{?? ??????/*?假設(shè)文件沒有被緩存。獲取緩存失敗?*/?? ??????NSLog(@"文件沒有緩存.");?? ??????[self.cacheDictionary?removeObjectForKey:paramURLAsString];?? ??????[self?saveCacheDictionary];?? ????}?/*?if?(cachedFileHasExpired?==?NO?&&?*/?? ?????? ??}?/*?if?(fileHasBeenCached?==?YES){?*/?? ???? ??/*?去下載文件?*/?? ???? ???? ??NSNumber?*expires?=??? ??[NSNumber?numberWithFloat:paramURLMustExpireInSeconds];?? ???? ??NSMutableDictionary?*newDictionary?=??? ??[[[NSMutableDictionary?alloc]?init]?autorelease];?? ???? ??[newDictionary?setObject:expires??? ????????????????????forKey:CachedKeyExpiresInSeconds];?? ???? ???? ??localURL?=?[paramURLAsString?? ??????????????stringByAddingPercentEscapesUsingEncoding:?? ??????????????NSUTF8StringEncoding];?? ???? ??localURL?=?[localURL?stringByReplacingOccurrencesOfString:@"://"?? ?????????????????????????????????????????????????withString:@""];?? ???? ??localURL?=?[localURL?stringByReplacingOccurrencesOfString:@"/"?? ?????????????????????????????????????????????????withString:@"{1}quot;];?? ???? ??localURL?=?[localURL?stringByAppendingPathExtension:@"cache"];?? ???? ??NSString?*documentsDirectory?=??? ??[self?documentsDirectoryWithTrailingSlash:NO];?? ???? ??localURL?=?[documentsDirectory??? ??????????????stringByAppendingPathComponent:localURL];?? ???? ??[newDictionary?setObject:localURL?? ????????????????????forKey:CachedKeyLocalURL];?? ???? ??[newDictionary?setObject:now?? ????????????????????forKey:CachedKeyDownloadStartDate];?? ???? ??[self.cacheDictionary?setObject:newDictionary?? ???????????????????????????forKey:paramURLAsString];?? ???? ??[self?saveCacheDictionary];?? ???? ??CacheItem?*item?=?[[[CacheItem?alloc]?init]?autorelease];?? ??[item?setDelegate:self];?? ??[item?startDownloadingURL:paramURLAsString];?? ???? ??return(result);?? ???? }?? 4、以下我們設(shè)計(jì)緩存項(xiàng)下載成功和失敗的兩個(gè)托付方法:
[plain]?view plaincopy
@protocol?CacheItemDelegate?<NSObject>?? //下載成功運(yùn)行該方法?? -?(void)?cacheItemDelegateSucceeded?? ??:(CacheItem?*)paramSender?? ??withRemoteURL:(NSURL?*)paramRemoteURL?? ??withAboutToBeReleasedData:(NSData?*)paramAboutToBeReleasedData;?? ?? //下載失敗運(yùn)行該方法?? -?(void)?cacheItemDelegateFailed?? ??:(CacheItem?*)paramSender?? ??remoteURL:(NSURL?*)paramRemoteURL?? ??withError:(NSError?*)paramError;?? ?? @end??
?? 當(dāng)我們下載成功的時(shí)候,改動(dòng)緩存字典中的下載時(shí)間,表示已經(jīng)下載完畢。并且須要將請求的資源數(shù)據(jù)緩存到本地:
[plain]?view plaincopy
//緩存項(xiàng)的托付方法?? -?(void)?cacheItemDelegateSucceeded:(CacheItem?*)paramSender?? ?????????withRemoteURL:(NSURL?*)paramRemoteURL?? ????????withAboutToBeReleasedData:(NSData?*)paramAboutToBeReleasedData{?? ???? ??//從緩存字典中獲取該緩存項(xiàng)的相關(guān)數(shù)據(jù)?? ??NSMutableDictionary?*dictionary?=??? ??[self.cacheDictionary?objectForKey:[paramRemoteURL?absoluteString]];?? ??//取當(dāng)前時(shí)間?? ??NSDate?*now?=?[NSDate?date];?? ??//獲取有效時(shí)間?? ??NSNumber?*expiresInSeconds?=?[dictionary??? ????????????????????????????????objectForKey:CachedKeyExpiresInSeconds];?? ??//轉(zhuǎn)換成NSTimeInterval?? ??NSTimeInterval?expirySeconds?=?[expiresInSeconds?floatValue];?? ??//改動(dòng)字典中緩存項(xiàng)的下載結(jié)束時(shí)間?? ??[dictionary?setObject:[NSDate?date]?? ?????????????????forKey:CachedKeyDownloadEndDate];?? ??//改動(dòng)字典中緩存項(xiàng)的緩存過期時(shí)間?? ??[dictionary?setObject:[now?dateByAddingTimeInterval:expirySeconds]?? ?????????????????forKey:CachedKeyExpiryDate];?? ??//保存緩存字典?? ??[self?saveCacheDictionary];?? ???? ??NSString?*localURL?=?[dictionary?objectForKey:CachedKeyLocalURL];?? ???? ??/*?將下載的數(shù)據(jù)保持到磁盤?*/?? ??if?([paramAboutToBeReleasedData?writeToFile:localURL?? ???????????????????????????????????atomically:YES]?==?YES){?? ????NSLog(@"緩存文件到磁盤成功.");?? ??}?else{?? ????NSLog(@"緩存文件到磁盤失敗.");?? ??}?? ??//運(yùn)行緩存管理的托付方法?? ??[self.delegate??? ???cachedDownloadManagerSucceeded:self?? ???remoteURL:paramRemoteURL?? ???localURL:[NSURL?URLWithString:localURL]?? ???aboutToBeReleasedData:paramAboutToBeReleasedData?? ???isCachedData:NO];?? ???? ???? }?? 假設(shè)下載失敗我們須要從緩存字典中移除改緩存項(xiàng):
[plain]?view plaincopy
//緩存項(xiàng)失敗失敗的托付方法?? -?(void)?cacheItemDelegateFailed:(CacheItem?*)paramSender?? ???????????????????????remoteURL:(NSURL?*)paramRemoteURL?? ???????????????????????withError:(NSError?*)paramError{?? ???? ??/*?從緩存字典中移除緩存項(xiàng),并發(fā)送一個(gè)托付?*/?? ???? ??if?(self.delegate?!=?nil){?? ?????? ????NSMutableDictionary?*dictionary?=??? ????[self.cacheDictionary??? ?????objectForKey:[paramRemoteURL?absoluteString]];?? ?????? ????NSString?*localURL?=?[dictionary??? ??????????????????????????objectForKey:CachedKeyLocalURL];?? ?????? ????[self.delegate?? ?????cachedDownloadManagerFailed:self?? ?????remoteURL:paramRemoteURL?? ?????localURL:[NSURL?URLWithString:localURL]?? ?????withError:paramError];?? ??}?? ???? ??[self.cacheDictionary??? ???removeObjectForKey:[paramRemoteURL?absoluteString]];?? ???? }?? 5、載入緩存字典的時(shí)候,我們能夠?qū)]有下載完畢的文件移除:
[plain]?view plaincopy
//初始化緩存字典?? ??NSString?*documentsDirectory?=??? ??[self?documentsDirectoryWithTrailingSlash:YES];?? ??//生產(chǎn)緩存字典的路徑?? ??cacheDictionaryPath?=??? ??[[documentsDirectory??? ????stringByAppendingString:@"CachedDownloads.dic"]?retain];?? ??//創(chuàng)建一個(gè)NSFileManager實(shí)例?? ??NSFileManager?*fileManager?=?[[NSFileManager?alloc]?init];?? ??//推斷是否存在緩存字典的數(shù)據(jù)?? ??if?([fileManager??? ???????fileExistsAtPath:self.cacheDictionaryPath]?==?YES){?? ??????NSLog(self.cacheDictionaryPath);?? ????//載入緩存字典中的數(shù)據(jù)?? ????NSMutableDictionary?*dictionary?=??? ????[[NSMutableDictionary?alloc]??? ?????initWithContentsOfFile:self.cacheDictionaryPath];?? ?????? ????cacheDictionary?=?[dictionary?mutableCopy];?? ?????? ????[dictionary?release];?? ?????? ????//移除沒有下載完畢的緩存數(shù)據(jù)?? ????[self?removeCorruptedCachedItems];?? ?????? ??}?else?{?? ????//創(chuàng)建一個(gè)新的緩存字典?? ????NSMutableDictionary?*dictionary?=??? ????[[NSMutableDictionary?alloc]?init];?? ?????? ????cacheDictionary?=?[dictionary?mutableCopy];?? ?????? ????[dictionary?release];?? ?????? ??}?? 這樣就基本上完畢了我們須要的功能。以下看看我們怎樣使用我們設(shè)計(jì)的緩存功能。 樣例場景:
??? 我們用一個(gè)UIWebView來顯示stackoverflow這個(gè)站點(diǎn),我們在這個(gè)站點(diǎn)的內(nèi)容緩存到本地20秒,假設(shè)在20秒內(nèi)用戶去請求該站點(diǎn),則從本地文件里獲取內(nèi)容,否則過了20秒。則又一次獲取數(shù)據(jù),并緩存到本地。
??? 在界面上拖放一個(gè)button和一個(gè)webview控件,例如以下圖。
?
??? 這樣我們能夠非常方便使用前面定義好的類。
我們在viewDidLoad 中實(shí)例化一個(gè)CachedDownloadManager,并設(shè)置它的托付為self。
當(dāng)下載完畢的時(shí)候。運(yùn)行CachedDownloadManager的下載成功的托付方法。
- (
void)viewDidLoad {[super viewDidLoad]; [self setTitle:
@"本地緩存測試"];CachedDownloadManager *newManager = [[CachedDownloadManager alloc] init];self.downloadManager = newManager;[newManager release];[self.downloadManager setDelegate:self];}
在button的點(diǎn)擊事件中增加以下代碼,請求stackoverflow :
static NSString *url =
@"http://stackoverflow.com";[self.downloadManager download:urlurlMustExpireInSeconds:
20.0fupdateExpiryDateIfInCache:YES];
??? 上面的代碼表示將這個(gè)stackoverflow的緩存事件設(shè)置為20s。而且假設(shè)在20s內(nèi)有同樣的請求,則從本地獲取stackoverflow的內(nèi)容數(shù)據(jù)。updateExpiryDateIfInCache設(shè)置為yes表示:在此請求的時(shí)候。緩存時(shí)間又更新為20s。類似我們的session。假設(shè)設(shè)置成no。則第一次請求20s之后。該緩存就過期。
??? 請求完畢之后會(huì)運(yùn)行CachedDownloadManager的托付方法。我們將數(shù)據(jù)展示在uiwebview中,代碼例如以下:
- (
void) cachedDownloadManagerSucceeded:(CachedDownloadManager *)paramSenderremoteURL:(NSURL *)paramRemoteURLlocalURL:(NSURL *)paramLocalURLaboutToBeReleasedData:(NSData *)paramAboutToBeReleasedDataisCachedData:(BOOL)paramIsCachedData{ [webview loadData:paramAboutToBeReleasedData MIMEType:
@"text/html" textEncodingName:
@"UTF-8" baseURL:[NSURL URLWithString:
@"http://stackoverflow.com"]];
}
這樣我們就實(shí)現(xiàn)了20s的緩存。
效果:
第一次點(diǎn)擊測試button:
?
20s內(nèi)點(diǎn)擊button,程序就從本地獲取數(shù)據(jù)。比較高速的就顯示出該網(wǎng)頁了。
?
總結(jié):
??? 本文通過代碼和實(shí)例設(shè)計(jì)了一個(gè)iPhone應(yīng)用程序本地緩存的方案。
當(dāng)然這個(gè)方法不是最好的,假設(shè)你有更好的思路。歡迎告訴我。
總結(jié)
以上是生活随笔為你收集整理的设计一个移动应用的本地缓存机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。