NSURLCache 和 NSCache 的区别

  • NSURLCache提供的是URL Request缓存,可以在Memory和Disk上;NSCache提供了HTTP Request外的东西的缓存方式,在Memory上。

  • NSCache和NSDictionary类似,不同的是系统回收内存的时候它会自动删掉它的内容。AFNetworking的图片缓存采用的就是NSCache。

  • NSURLCache一般用于UIWebView,只对异步请求有效,程序中只有一个NSURLCache,为了使响应更灵敏而且更像本地用户界面。

NSURLCache详解

NSURLCache 为您的应用的 URL 请求提供了内存中以及磁盘上的综合缓存机制。 作为基础类库 URL 加载系统 的一部分,任何通过 NSURLConnection 加载的请求都将被 NSURLCache 处理。网络缓存减少了需要向服务器发送请求的次数,同时也提升了离线或在低速网络中使用应用的体验。
当一个请求完成下载来自服务器的回应,一个缓存的回应将在本地保存。下一次同一个请求再发起时,本地保存的回应就会马上返回,不需要连接服务器。NSURLCache 会自动透明地返回回应。
为了好好利用 NSURLCache,你需要初始化并设置一个共享的 URL 缓存。在 iOS 中,需要在 -application:didFinishLaunchingWithOptions: 完成,而 Mac OS X 中是在 –applicationDidFinishLaunching。

  1. 创建

    NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil];
    [NSURLCache setSharedURLCache:URLCache];

    默认情况下,内存是4M,4 1024 1024;Disk为20M,20 * 1024 * 1024;路径(diskPath)在(NSHomeDirectory)/Library/Caches/(current application name, [[NSProcessInfo processInfo] processName])。

  2. NSURLCache使用的常用方法

    -(NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request;如果对应的NSURLRequest没有cached的response那么返回nil
    -(void)storeCachedResponse:(NSCachedURLResponse *)cachedResponse forRequest:(NSURLRequest *)request;为特定的NSURLRequest做cache
    -(void)removeCachedResponseForRequest:(NSURLRequest *)request;移除特定NSURLRequest的cache
    -(void)removeAllCachedResponses; 移除所有的cache
  3. 缓存的几种方式
    缓存策略由请求(客户端)和回应(服务端)分别指定。
    NSURLRequest 有个 cachePolicy 属性,它根据以下常量指定了请求的缓存行为:

    UseProtocolCachePolicy                     默认行
    ReloadIgnoringLocalCacheData 不使用缓存
    -ReloadIgnoringLocalAndRemoteCacheData- 我是认真地,不使用任何缓存
    ReturnCacheDataElseLoad 使用缓存(不管它是否过期),如果缓存中没有,那从网络加载吧
    ReturnCacheDataDontLoad 离线模式:使用缓存(不管它是否过期),但是不从网络加载
    -ReloadRevalidatingCacheData- 在使用前去服务器验证
  4. HTTP 缓存语义
    因为 NSURLConnection 被设计成支持多种协议——包括 FTP、HTTP、HTTPS——所以 URL 加载系统用一种协议无关的方式指定缓存。为了本文的目的,缓存用术语 HTTP 语义来解释。
    HTTP 请求和回应用 headers 来交换元数据,如字符编码、MIME 类型和缓存指令等。

Request Cache Headers

在默认情况下,NSURLRequest 会用当前时间决定是否返回缓存的数据。为了更精确地控制,允许使用以下请求头:

Modified-Since-    这个请求头与 Last-Modified 回应头相对应。把这个值设为同一终端最后一次请求时返回的Last-Modified 字段的值。
If-None-Match- 这个请求头与 Etag 回应头相对应。使用同一终端最后一次请求的Etag值。

Response Cache Headers

NSHTTPURLResponse 包含多个 HTTP 头,当然也包括以下指令来说明回应应当如何缓存:

Cache-Control - 这个头必须由服务器端指定以开启客户端的 HTTP 缓存功能。这个头的值可能包含 max-age(缓存多久),是公共 public 还是私有 private,或者不缓存 no-cache等信息。

除了 Cache-Control 以外,服务器也可能发送一些附加的头用于根据需要有条件地请求:

Last-Modified -    这个头的值表明所请求的资源上次修改的时间。例如,一个客户端请求最近照片的时间线,/photos/timeline,Last-Modified 的值可以是最近一张照片的拍摄时间。
Etag - 这是 “entity tag” 的缩写,它是一个表示所请求资源的内容的标识符。在实践中,Etag 的值可以是类似于资源的 MD5 之类的东西。这对于那些动态生成的、可能没有明显的 Last-Modified 值的资源非常有用。

NSURLConnectionDelegate

一旦收到了服务器的回应,NSURLConnection 的代理就有机会在 -connection:willCacheResponse: 中指定缓存数据。
所以缓存实际在NSCachedURLResponse这个类中。NSCachedURLResponse 是个包含 NSURLResponse 以及它对应的缓存中的 NSData 的类。
在 -connection:willCacheResponse: 中,cachedResponse 对象会根据 URL 连接返回的结果自动创建。
因为 NSCachedURLResponse 没有可变部分,为了改变 cachedResponse 中的值必须构造一个新的对象,把改变过的值传入 –initWithResponse:data:userInfo:storagePolicy:,例如:

(NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse{
NSMutableDictionary *mutableUserInfo = [[cachedResponse userInfo] mutableCopy];
NSMutableData *mutableData = [[cachedResponse data] mutableCopy];
NSURLCacheStoragePolicy storagePolicy = NSURLCacheStorageAllowedInMemoryOnly;
return [[NSCachedURLResponse alloc] initWithResponse:[cachedResponse response]data:mutableData userInfo:mutableUserInfo storagePolicy:storagePolicy];
}

如果 -connection:willCacheResponse: 返回 nil,回应将不会缓存。

(NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse{
return nil;
}

如果不实现此方法,NSURLConnection 就简单地使用本来要传入 -connection:willCacheResponse: 的那个缓存对象,所以除非你需要改变一些值或者阻止缓存,否则这个代理方法不必实现。

NSCache 使用

NSCache *myCache = ...;
NSAssert(myCache != nil, @"cache object is missing");
Widget *myWidget = [myCache objectForKey: @"Important Widget"];
if (!myWidget) {
myWidget = [[[Widget alloc] initExpensively] autorelease];
[myCache setObject: myWidget forKey: @"Important Widget"];
}
if (myWidget) {
[myWidget runOrWhatever];
}

 

NSURLCache 和 NSCache 的区别的更多相关文章

  1. NSCache和NSURLCache、网络缓存优化

    本文目录 一种缓存优化方案 响应头'Last-Modified'和请求头'If-Modified-Since' 'Keep-Alive'响应头和不离线的URLSession 'Expires'响应头 ...

  2. NSURLCache

    属性介绍: //获取当前应用的缓存管理对象 + (NSURLCache *)sharedURLCache; //设置自定义的NSURLCache作为应用缓存管理对象 + (void)setShared ...

  3. c#与java的区别

    经常有人问这种问题,用了些时间java之后,发现这俩玩意除了一小部分壳子长的还有能稍微凑合上,基本上没什么相似之处,可以说也就是马甲层面上的相似吧,还是比较短的马甲... 一般C#多用于业务系统的开发 ...

  4. jquery和Js的区别和基础操作

    jqery的语法和js的语法一样,算是把js升级了一下,这两种语法可以一起使用,只不过是用jqery更加方便 一个页面想要使用jqery的话,先要引入一下jqery包,jqery包从网上下一个就可以, ...

  5. 【原】nodejs全局安装和本地安装的区别

    来微信支付有2年多了,从2年前的互联网模式转变为O2O模式,主要的场景是跟线下的商户去打交道,不像以往的互联网模式,有产品经理提需求,我们帮忙去解决问题. 转型后是这样的,团队成员更多需要去寻找业务的 ...

  6. 探究@property申明对象属性时copy与strong的区别

    一.问题来源 一直没有搞清楚NSString.NSArray.NSDictionary--属性描述关键字copy和strong的区别,看别人的项目中属性定义有的用copy,有的用strong.自己在开 ...

  7. X86和X86_64和X64有什么区别?

    x86是指intel的开发的一种32位指令集,从386开始时代开始的,一直沿用至今,是一种cisc指令集,所有intel早期的cpu,amd早期的cpu都支持这种指令集,ntel官方文档里面称为&qu ...

  8. Java中Comparable与Comparator的区别

    相同 Comparable和Comparator都是用来实现对象的比较.排序 要想对象比较.排序,都需要实现Comparable或Comparator接口 Comparable和Comparator都 ...

  9. MySQL中interactive_timeout和wait_timeout的区别

    在用mysql客户端对数据库进行操作时,打开终端窗口,如果一段时间没有操作,再次操作时,常常会报如下错误: ERROR (HY000): Lost connection to MySQL server ...

随机推荐

  1. 提高Oracle的WHERE语句性能一些原则

    索引是表的一个概念部分 , 用来提高检索数据的效率, ORACLE 使用了一个复杂的自平衡 B-tree 结构 . 通常 , 通过索引查询数据比全表扫描要快 . 当 ORACLE 找出执行查询和 Up ...

  2. PythonPP+lambda:示例

    直接上代码. python PP 下载, 可以到官网下载 Python PP 下载 lambda 能做的, 基本上普通函数都可以做到. lambda 的主要作用是简化表达式, 并且似乎尤其适合于表达科 ...

  3. UnicodeDecodeError: 'utf8' codec can't decode byte 0xce in position 47: invalid continuation byte

  4. 关于img 403 forbidden的一些思考

    网页中经常需要显示图片给用户看,对网站本身来说有的图片是从本地图片服务器来的,但是一旦数量多了以后,磁盘空间又是一个问题. 所以有时就希望显示其他网站的Image,直接把其他网站的图片显示在我的网站上 ...

  5. JS中iframe相关的window.self,window.parent,window.top

    window.self指的是当前窗口:他等价于window,self,window.self window.top指的是最顶层的窗口(有些页面可能会嵌套好几个iframe)如果只有一个窗口,那么就返回 ...

  6. if,else语句的运用

    1.求解一元二次方程 Console.WriteLine("求解一元二次方程:a*x*x+b*x+c=0"); Console.Write("请输入 a="); ...

  7. 【iOS】UIKit框架 学习笔记

    ... ...

  8. 查看占用cpu和内存最多的进程

    linux下获取占用CPU资源最多的10个进程,可以使用如下命令组合: ps aux|head -;ps aux|grep -v PID|sort -rn -k +|head linux下获取占用内存 ...

  9. How To Use DBLink In Oracle Forms 6i

    You want to connect multiple databases in oracle forms to perform certain tasks, for example you nee ...

  10. C#:Hashtable和Dictionary

    Dictionary<TKey, TValue> ()      Hashtable() 第一.存储的数据类型 Hashtable不是泛型的,不是类型安全的:Dictionary是泛型的, ...