本地缓存机制之二






4、下面我们设计缓存项下载成功和失败的两个委托方法:

  1. @protocol CacheItemDelegate <NSObject>

  2. //下载成功执行该方法

  3. - (void) cacheItemDelegateSucceeded

  4. :(CacheItem *)paramSender

  5. withRemoteURL:(NSURL *)paramRemoteURL

  6. withAboutToBeReleasedData:(NSData
    *)paramAboutToBeReleasedData;
  7. //下载失败执行该方法

  8. - (void) cacheItemDelegateFailed

  9. :(CacheItem *)paramSender

  10. remoteURL:(NSURL *)paramRemoteURL

  11. withError:(NSError *)paramError;
  12. @end

复制代码

当我们下载成功的时候,修改缓存字典中的下载时间,表示已经下载完成,而且需要将请求的资源数据缓存到本地:

  1. //缓存项的委托方法

  2. - (void) cacheItemDelegateSucceeded:(CacheItem
    *)paramSender

  3. withRemoteURL:(NSURL
    *)paramRemoteURL

  4. withAboutToBeReleasedData:(NSData
    *)paramAboutToBeReleasedData{
  5. //从缓存字典中获取该缓存项的相关数据

  6. NSMutableDictionary *dictionary =

  7. [self.cacheDictionary objectForKey:[paramRemoteURL
    absoluteString]];

  8. //取当前时间

  9. NSDate *now = [NSDate date];

  10. //获取有效时间

  11. NSNumber *expiresInSeconds = [dictionary

  12. objectForKey:CachedKeyExpiresInSeconds];

  13. //转换成NSTimeInterval

  14. NSTimeInterval expirySeconds = [expiresInSeconds
    floatValue];

  15. //修改字典中缓存项的下载结束时间

  16. [dictionary setObject:[NSDate date]

  17. forKey:CachedKeyDownloadEndDate];

  18. //修改字典中缓存项的缓存过期时间

  19. [dictionary setObject:[now
    dateByAddingTimeInterval:expirySeconds]

  20. forKey:CachedKeyExpiryDate];

  21. //保存缓存字典

  22. [self saveCacheDictionary];
  23. NSString *localURL = [dictionary
    objectForKey:CachedKeyLocalURL];
  24. /* 将下载的数据保持到磁盘 */

  25. if ([paramAboutToBeReleasedData
    writeToFile:localURL

  26. atomically:YES] ==
    YES){

  27. NSLog(@"缓存文件到磁盘成功.");

  28. } else{

  29. NSLog(@"缓存文件到磁盘失败.");

  30. }

  31. //执行缓存管理的委托方法

  32. [self.delegate

  33. cachedDownloadManagerSucceeded:self

  34. remoteURL:paramRemoteURL

  35. localURL:[NSURL
    URLWithString:localURL]

  36. aboutToBeReleasedData:paramAboutToBeReleasedData

  37. isCachedData:NO];
  38. }

复制代码

如果下载失败我们需要从缓存字典中移除改缓存项:

  1. //缓存项失败失败的委托方法

  2. - (void) cacheItemDelegateFailed:(CacheItem
    *)paramSender

  3. remoteURL:(NSURL
    *)paramRemoteURL

  4. withError:(NSError
    *)paramError{
  5. /* 从缓存字典中移除缓存项,并发送一个委托 */
  6. if (self.delegate != nil){
  7. NSMutableDictionary *dictionary =

  8. [self.cacheDictionary

  9. objectForKey:[paramRemoteURL
    absoluteString]];
  10. NSString *localURL = [dictionary

  11. objectForKey:CachedKeyLocalURL];
  12. [self.delegate

  13. cachedDownloadManagerFailed:self

  14. remoteURL:paramRemoteURL

  15. localURL:[NSURL
    URLWithString:localURL]

  16. withError:paramError];

  17. }
  18. [self.cacheDictionary

  19. removeObjectForKey:[paramRemoteURL
    absoluteString]];
  20. }

复制代码

5、加载缓存字典的时候,我们可以将没有下载完成的文件移除:

  1. //初始化缓存字典

  2. NSString *documentsDirectory =

  3. [self
    documentsDirectoryWithTrailingSlash:YES];

  4. //生产缓存字典的路径

  5. cacheDictionaryPath =

  6. [[documentsDirectory

  7. stringByAppendingString:@"CachedDownloads.dic"]
    retain];

  8. //创建一个NSFileManager实例

  9. NSFileManager *fileManager = [[NSFileManager alloc]
    init];

  10. //判断是否存在缓存字典的数据

  11. if ([fileManager

  12. fileExistsAtPath:self.cacheDictionaryPath] ==
    YES){

  13. NSLog(self.cacheDictionaryPath);

  14. //加载缓存字典中的数据

  15. NSMutableDictionary *dictionary =

  16. [[NSMutableDictionary alloc]

  17. initWithContentsOfFile:self.cacheDictionaryPath];
  18. cacheDictionary = [dictionary
    mutableCopy];
  19. [dictionary release];
  20. //移除没有下载完成的缓存数据

  21. [self
    removeCorruptedCachedItems];
  22. } else {

  23. //创建一个新的缓存字典

  24. NSMutableDictionary *dictionary =

  25. [[NSMutableDictionary alloc]
    init];
  26. cacheDictionary = [dictionary
    mutableCopy];
  27. [dictionary release];
  28. }

复制代码

 
     这样就基本上完成了我们需要的功能,下面看看我们如何使用我们设计的缓存功能。

例子场景:

我们用一个UIWebView来显示stackoverflow这个网站,我们在这个网站的内容缓存到本地20秒,如果在20秒内用户去请求该网站,则从本地文件中获取内容,否则过了20秒,则重新获取数据,并缓存到本地。

在界面上拖放一个button和一个webview控件,如下图。

<ignore_js_op>

这样我们可以很方便使用前面定义好的类。我们在viewDidLoad
中实例化一个CachedDownloadManager,并设置它的委托为self。当下载完成的时候,执行CachedDownloadManager的下载成功的委托方法。

  1. - (void)viewDidLoad { [super viewDidLoad]; [self
    setTitle:@"本地缓存测试"]; CachedDownloadManager *newManager
    =[[CachedDownloadManager alloc] init]; self.downloadManager =
    newManager; [newManager release]; [self.downloadManager
    setDelegate:self]; }

复制代码

在button的点击事件中加入下面代码,请求stackoverflow :

  1. static NSString *url = @"http://stackoverflow.com";
    [self.downloadManager download:url urlMustExpireInSeconds:20.0f
    updateExpiryDateIfInCache:YES];

复制代码

上面的代码表示将这个stackoverflow的缓存事件设置为20s,并且如果在20s内有相同的请求,则从本地获取stackoverflow的内容数据。updateExpiryDateIfInCache设置为yes表示:在此请求的时候,缓存时间又更新为20s,类似我们的session。如果设置成no,则第一次请求20s之后,该缓存就过期。

请求完成之后会执行CachedDownloadManager的委托方法。我们将数据展示在uiwebview中,代码如下:

  1. - (void) cachedDownloadManagerSucceeded:(CachedDownloadManager
    *)paramSender remoteURL:(NSURL *)paramRemoteURL localURL:(NSURL
    *)paramLocalURL aboutToBeReleasedData:(NSData
    *)paramAboutToBeReleasedData isCachedData:(BOOL)paramIsCachedData{
    [webview loadData:paramAboutToBeReleasedData
    MIMEType:@"text/html"textEncodingName:@"UTF-8" baseURL:[NSURL
    URLWithString:@"http://stackoverflow.com"]];
    }

复制代码

这样我们就实现了20s的缓存。

效果:

第一次点击测试按钮:

<ignore_js_op>

20s内点击按钮,程序就从本地获取数据,比较快速的就显示出该网页了。

总结:

本文通过代码和实例设计了一个iPhone应用程序本地缓存的方案。当然这个方案不是最好的,如果你有更好的思路,欢迎告诉我。


本地缓存机制之二,布布扣,bubuko.com

时间: 2024-10-11 01:04:54

本地缓存机制之二的相关文章

本地缓存机制之一

在手机应用程序开发中,为了减少与服务端的交互次数,加快用户的响应速度,一般都会在iOS设备中加一个缓存的机制,前面一篇文章介绍了iOS设备的内存缓存,这篇文章将设计一个本地缓存的机制. 功能需求 这个缓存机制满足下面这些功能. 1.可以将数据缓存到本地磁盘. 2.可以判断一个资源是否已经被缓存.如果已经被缓存,在请求相同的资源,先到本地磁盘搜索. 3.可以判断文件缓存什么时候过期.这里为了简单起见这里,我们在请求url资源的时候,给每次请求的文件设定一个过期的时间. 4.可以实现:如果文件已经被

设计一个移动应用的本地缓存机制

在手机应用程序开发中,为了降低与服务端的交互次数,加快用户的响应速度,一般都会在iOS设备中加一个缓存的机制,前面一篇文章介绍了iOS设备的内存缓存.这篇文章将设计一个本地缓存的机制. 功能需求 这个缓存机制满足以下这些功能. 1.能够将数据缓存到本地磁盘. 2.能够推断一个资源是否已经被缓存.假设已经被缓存.在请求同样的资源.先到本地磁盘搜索. 3.能够推断文件缓存什么时候过期.这里为了简单起见这里,我们在请求url资源的时候.给每次请求的文件设定一个过期的时间. 4.能够实现:假设文件已经被

MVC 之 缓存机制(二)

八.应用程序缓存 应用程序缓存提供了一种编程方式,可通过键/值对将任意数据存储在内存中. 使用应用程序缓存与使用应用程序状态类似. 但是,与应用程序状态不同的是,应用程序缓存中的数据是易失的, 即数据并不是在整个应用程序生命周期中都存储在内存中. 使用应用程序缓存的优点是由 ASP.NET 管理缓存,它会在项过期.无效.或内存不足时移除缓存中的项. 还可以配置应用程序缓存,以便在移除项时通知应用程序. 应用程序缓存的使用模式:确定在访问某一项时该项是否存在于缓存中,如果存在,则使用. 如果该项不

Unity+NGUI打造网络图片异步加载与本地缓存工具类(二)

接上文,我们的工具类中的主要方法: public  void SetAsyncImage(string url,UITexture texture) 按照前文分析的图片加载步骤来 public void SetAsyncImage(string url,UITexture texture){ //开始下载图片前,将UITexture的主图片设置为占位图 texture.mainTexture = placeholder; //判断是否是第一次加载这张图片 if (!File.Exists (pa

Mybatis——缓存机制

MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制.缓存可以极大的提升查询效率. MyBatis系统中默认定义了两级缓存. 一级缓存和二级缓存. 1.默认情况下,只有一级缓存(SqlSession级别的缓存,也称为本地缓存)开启.2.二级缓存需要手动开启和配置,他是基于namespace级别的缓存.3.为了提高扩展性.MyBatis定义了缓存接口Cache.我们可以通过实现Cache接口来自定义二级缓存 一.一级缓存 一级缓存(local cache), 即本地缓存, 作

深度解析浏览器的缓存机制

一.前言 缓存可以说是性能优化中简单高效的一种优化方式了.一个优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,并且由于缓存文件可以重复利用,还可以减少带宽,降低网络负荷. 对于一个数据请求来说,可以分为发起网络请求.后端处理.浏览器响应三个步骤.浏览器缓存可以帮助我们在第一和第三步骤中优化性能.比如说直接使用缓存而不发起请求,或者发起了请求但后端存储的数据和前端一致,那么就没有必要再将数据回传回来,这样就减少了响应数据. 接下来的内容中我们将通过缓存位置.缓存策略以及实际场景应用缓存策略来探

浅谈Hibernate缓存机制:一级缓存、二级缓存

一:什么是缓存机制 当我们频繁访问数据库时,尤其像Hibernate持久层框架,会导致数据库访问性能降低,因此我们期望有一种机制能提供一个"缓存空间",我们将需要的数据复制到这个"缓存空间",当数据查询时,我们先在这个"缓存空间"里找,如果没有,我们再去数据库查找,这样就减少了与数据库的访问,从而提高了数据库访问性能,这就是缓存机制. 二:Hibernate缓存机制 1:一级缓存:Hibernate默认的缓存机制,它属于Session级别的缓存机

Mybatis的一级缓存机制简介

1.接口 public interface MemberMapperCache { public Members selectMembersById(Integer id); } 2.配置文件xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://my

Java缓存学习之二:浏览器缓存机制

浏览器端的九种缓存机制介绍 浏览器缓存是浏览器端保存数据用于快速读取或避免重复资源请求的优化机制,有效的缓存使用可以避免重复的网络请求和浏览器快速地读取本地数据,整体上加速网页展示给用户.浏览器端缓存的机制种类较多,总体归纳为九种,这里详细分析下这九种缓存机制的原理和使用场景.打开浏览器的调试模式->resources左侧就有浏览器的8种缓存机制. 一.http缓存 http缓存是基于HTTP协议的浏览器文件级缓存机制.即针对文件的重复请求情况下,浏览器可以根据协议头判断从服务器端请求文件还是从