nsurlrequestusensurlprotocollcachepolicy 怎么缓存

NSURLCache - NSHipster
NSURLCache 为您的应用的 URL 请求提供了内存中以及磁盘上的综合缓存机制。 作为基础类库
的一部分,任何通过 NSURLConnection 加载的请求都将被 NSURLCache 处理。
网络缓存减少了需要向服务器发送请求的次数,同时也提升了离线或在低速网络中使用应用的体验。
当一个请求完成下载来自服务器的回应,一个缓存的回应将在本地保存。下一次同一个请求再发起时,本地保存的回应就会马上返回,不需要连接服务器。NSURLCache 会 自动 且 透明 地返回回应。
为了好好利用 NSURLCache,你需要初始化并设置一个共享的 URL 缓存。在 iOS 中这项工作需要在 -application:didFinishLaunchingWithOptions: 完成,而 OS X 中是在 –applicationDidFinishLaunching::
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024
diskCapacity:20 * 1024 * 1024
diskPath:nil];
[NSURLCache setSharedURLCache:URLCache];
缓存策略由请求(客户端)和回应(服务端)分别指定。理解这些策略以及它们如何相互影响,是为您的应用程序找到最佳行为的关键。
NSURLRequestCachePolicy
NSURLRequest 有个 cachePolicy 属性,它根据以下常量指定了请求的缓存行为:
NSURLRequestUseProtocolCachePolicy: 对特定的 URL 请求使用网络协议中实现的缓存逻辑。这是默认的策略。
NSURLRequestReloadIgnoringLocalCacheData:数据需要从原始地址加载。不使用现有缓存。
NSURLRequestReloadIgnoringLocalAndRemoteCacheData:不仅忽略本地缓存,同时也忽略代理服务器或其他中间介质目前已有的、协议允许的缓存。
NSURLRequestReturnCacheDataElseLoad:无论缓存是否过期,先使用本地缓存数据。如果缓存中没有请求所对应的数据,那么从原始地址加载数据。
NSURLRequestReturnCacheDataDontLoad:无论缓存是否过期,先使用本地缓存数据。如果缓存中没有请求所对应的数据,那么放弃从原始地址加载数据,请求视为失败(即:“离线”模式)。
NSURLRequestReloadRevalidatingCacheData:从原始地址确认缓存数据的合法性后,缓存数据就可以使用,否则从原始地址加载。
你并不会惊奇于这些值不被透彻理解且经常搞混淆。
NSURLRequestReloadIgnoringLocalAndRemoteCacheData 和 NSURLRequestReloadRevalidatingCacheData ()更加加深了混乱程度!
关于NSURLRequestCachePolicy,以下才是你 实际 需要了解的东西:
UseProtocolCachePolicy
ReloadIgnoringLocalCacheData
不使用缓存
ReloadIgnoringLocalAndRemoteCacheData
我是认真地,不使用任何缓存
ReturnCacheDataElseLoad
使用缓存(不管它是否过期),如果缓存中没有,那从网络加载吧
ReturnCacheDataDontLoad
离线模式:使用缓存(不管它是否过期),但是不从网络加载
ReloadRevalidatingCacheData
在使用前去服务器验证
HTTP 缓存语义
因为 NSURLConnection 被设计成支持多种协议——包括 FTP、HTTP、HTTPS——所以 URL 加载系统用一种协议无关的方式指定缓存。为了本文的目的,缓存用术语 HTTP 语义来解释。
HTTP 请求和回应用
来交换元数据,如字符编码、MIME 类型和缓存指令等。
在默认情况下,NSURLRequest 会用当前时间决定是否返回缓存的数据。为了更精确地控制,允许使用以下请求头:
If-Modified-Since - 这个请求头与 Last-Modified 回应头相对应。把这个值设为同一终端最后一次请求时返回的 Last-Modified 字段的值。
If-None-Match - 这个请求头与与 Etag 回应头相对应。使用同一终端最后一次请求的 Etag 值。
NSHTTPURLResponse 包含多个 HTTP 头,当然也包括以下指令来说明回应应当如何缓存:
Cache-Control - 这个头必须由服务器端指定以开启客户端的 HTTP 缓存功能。这个头的值可能包含 max-age(缓存多久),是公共 public 还是私有 private,或者不缓存 no-cache 等信息。详情请参阅 。
除了 Cache-Control 以外,服务器也可能发送一些附加的头用于根据需要有条件地请求(如上一节所提到的):
Last-Modified - 这个头的值表明所请求的资源上次修改的时间。例如,一个客户端请求最近照片的时间线,/photos/timeline,Last-Modified 的值可以是最近一张照片的拍摄时间。
Etag - 这是 “entity tag” 的缩写,它是一个表示所请求资源的内容的标识符。在实践中,Etag 的值可以是类似于资源的
之类的东西。这对于那些动态生成的、可能没有明显的 Last-Modified 值的资源非常有用。
NSURLConnectionDelegate
一旦收到了服务器的回应,NSURLConnection 的代理就有机会在 -connection:willCacheResponse: 中指定缓存数据。
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: 的那个缓存对象,所以除非你需要改变一些值或者阻止缓存,否则这个代理方法不必实现。
正如它那个毫无关系但是名字相近的小伙伴
一样,NSURLCache 也是有一些特别的。
在 iOS 5,磁盘缓存开始支持,但仅支持 HTTP,非 HTTPS(iOS 6 中增加了此支持)。Peter Steinberger ,在深入研究内部细节后实现。
描述了一些与服务器通信时不设置缓存头的意外的默认行为。
NSURLCache 提醒着我们熟悉我们正在操作的系统是多么地重要。开发 iOS 或 OS X 程序时,这些系统中的重中之重,非 莫属。
无数开发者尝试自己做一个简陋而脆弱的系统来实现网络缓存的功能,殊不知 NSURLCache 只要两行代码就能搞定且好上100倍。甚至更多开发者根本不知道网络缓存的好处,也从未尝试过,导致他们的应用向服务器作了无数不必要的网络请求。
所以如果你想看到世界的变化,你想确保你有程序总以正确的方式开启,在 -application:didFinishLaunchingWithOptions: 设置一个共享的 NSURLCache 吧。
() is the creator & maintainer of
and other popular , including ,
Ricky Tan 是 iOS 版 3.1.3 以前版本及后台、Xcode 插件
的开发者,另有浙大网址导航
插件等。。
下一篇文章
打破了苹果API排他性的盾牌,本期NSHipster将介绍一个为Objective-C勇敢构建新纪元的开源项目:ReactiveCocoa
NSNotification &NSNotificationCenter
除非另有声明、本网站采用知识共享「」许可协议授权。
本站文章由
Lin Xiangyu
Sheldon Huang
Yifan Xiao10225人阅读
iphone开发(181)
1.NSURLRequestUseProtocolCachePolicy NSURLRequest & & & & & & & & &默认的cache policy,使用Protocol协议定义。
2.NSURLRequestReloadIgnoringCacheData & & & & & & & & & & & & & & & & & & & &忽略缓存直接从原始地址下载。
3.NSURLRequestReturnCacheDataDontLoad & & & & & & & & & & & & & & & & & & 只使用cache数据,如果不存在cache,请求失败;用于没有建立网络连接离线模式
4.NSURLRequestReturnCacheDataElseLoad & & & & & & & & & & & & & & & & & & 只有在cache中不存在data时才从原始地址下载。
5.NSURLRequestReloadIgnoringLocalAndRemoteCacheData & & & & & 忽略本地和远程的缓存数据,直接从原始地址下载,与NSURLRequestReloadIgnoringCacheData类似。
6.NSURLRequestReloadRevalidatingCacheData & & & & & & & & & & & & & & &:验证本地数据与远程数据是否相同,如果不同则下载远程数据,否则使用本地数据
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:474387次
积分:5498
积分:5498
排名:第3963名
原创:77篇
转载:129篇
评论:30条
(1)(1)(2)(1)(2)(3)(1)(3)(4)(1)(2)(2)(1)(1)(2)(3)(4)(6)(10)(2)(1)(8)(11)(10)(8)(8)(25)(40)(21)(22)NSURLRequestCachePolicy—iOS缓存策略 | 阿凡树的博客
& NSURLRequestCachePolicy—iOS缓存策略
3,150 次阅读
  NSURLRequestCachePolicy指定缓存逻辑。URL加载系统提供了一个磁盘和内存混合的缓存,来相应网络请求。这个缓存允许一个应用减少对网络连接的依赖,并且增加性能。使用缓存的目的是为了使用的应用程序能更快速的响应用户输入,是程序高效的运行。有时候我们需要将远程web服务器获取的数据缓存起来,减少对同一个url多次请求。
  NSURLRequestUseProtocolCachePolicy = 0,
默认缓存策略。具体工作:如果一个NSCachedURLResponse对于请求并不存在,数据将会从源端获取。如果请求拥有一个缓存的响应,那么URL加载系统会检查这个响应来决定,如果它指定内容必须重新生效的话。假如内容必须重新生效,将建立一个连向源端的连接来查看内容是否发生变化。假如内容没有变化,那么响应就从本地缓存返回数据。如果内容变化了,那么数据将从源端获取
  NSURLRequestReloadIgnoringLocalCacheData = 1,
URL应该加载源端数据,不使用本地缓存数据
  NSURLRequestReloadIgnoringLocalAndRemoteCacheData =4, 本地缓存数据、代理和其他中介都要忽视他们的缓存,直接加载源数据
  NSURLRequestReloadIgnoringCacheData =
NSURLRequestReloadIgnoringLocalCacheData, 两个的设置相同
  NSURLRequestReturnCacheDataElseLoad = 2,
指定已存的缓存数据应该用来响应请求,不管它的生命时长和过期时间。如果在缓存中没有已存数据来响应请求的话,数据从源端加载。
  NSURLRequestReturnCacheDataDontLoad = 3,
指定已存的缓存数据用来满足请求,不管生命时长和过期时间。如果在缓存中没有已存数据来响应URL加载请求的话,不去尝试从源段加载数据,此时认为加载请求失败。这个常量指定了一个类似于离线模式的行为
  NSURLRequestReloadRevalidatingCacheData = 5 指定如果已存的缓存数据被提供它的源段确认为有效则允许使用缓存数据响应请求,否则从源段加载数据。
  只有响应http和https的请求会被缓存。ftp和文件协议当被缓存策略允许的时候尝试接入源段。自定义的NSURLProtocol类能够保护缓存,如果它们被选择使用的话。
  小结:NSURLRequestReturnCacheDataDontLoad是用于离线模式的,我为了能让用户在离线下面阅读,我就设计了当没有网络的时候的策略为NSURLRequestReturnCacheDataDontLoad。
if (有网) {
cachePolicy = NSURLRequestUseProtocolCacheP
cachePolicy = NSURLRequestReturnCacheDataDontL
转载请注明: 转载自
本文链接地址:
( 0 )  “类族”(class cluster)是一种很有用的模式(pattern),可以隐藏“抽象基类”(abs...
( 0 )  在实现这个自定义的初始化方法时,一定要遵循属性定义中宣称的“copy”语义,因为“属...
( 14 )  置顶更新:最近写了一个MAC版的APP来分割有plist文件的精灵表(照顾用python脚本总是出...
( 0 )  SSKeyChains对苹果安全框架API进行了简单封装,支持对存储在钥匙串中密码、账户进行访...
( 4 )什么是GCD?  Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程...
评论提交中, 请稍候...
Trackbacks & Pingbacks ( 0 )
还没有 trackbacks
2017年三月
6789101112
13141516171819
20212223242526
2728293031TA的最新馆藏玩转iOS开发 - 数据缓存
时间: 08:36:48
&&&& 阅读:492
&&&& 评论:
&&&& 收藏:0
有时候。对同一个URL请求多次,返回的数据可能都是一样的,比方server上的某张图片。不管下载多少次,返回的数据都是一样的。
上面的情况会造成下面问题
(1)用户流量的浪费
(2)程序响应速度不够快
解决上面的问题。一般考虑对数据进行缓存。
为了提高程序的响应速度,能够考虑使用缓存(内存缓存\硬盘缓存)r
第一次请求数据时,内存缓存中没有数据。硬盘缓存中没有数据。
缓存数据的过程:
? 当server返回数据时,须要做下面步骤
(1)使用server的数据(比方解析、显示)
(2)将server的数据缓存到硬盘(沙盒)
此时缓存的情况是:内存缓存中有数据,硬盘缓存中有数据。
? 再次请求数据分为两种情况:
(1)假设程序并没有被关闭,一直在执行
请求数据-& 内存数据
(2)假设程序又一次启动
请求数据-&硬盘数据-& 再次请求数据-& 内存数据
提示:数据从硬盘读入内存-& 程序开启-& 内存中一直有数据
缓存的实现
? 因为GET请求一般用来查询数据
? POST请求通常是发大量数据给server处理(变动性比較大)
=&因此一般仅仅对GET请求进行缓存,而不正确POST请求进行缓存
? 在iOS中。能够使用NSURLCache类缓存数据
? iOS 5之前:仅仅支持内存缓存。从iOS 5開始:同一时候支持内存缓存和硬盘缓存
NSURLCache
iOS中得缓存技术用到了NSURLCache类。
? 缓存原理:一个NSURLRequest相应一个NSCachedURLResponse
? 缓存技术:把缓存的数据都保存到数据库中。
NSURLCache的常见使用方法
(1)获得全局缓存对象(不是必需手动创建)
NSURLCache *cache = [NSURLCache sharedURLCache];
(2)设置内存缓存的最大容量(字节为单位,默觉得512KB)
- (void)setMemoryCapacity:(NSUInteger)memoryC
(3)设置硬盘缓存的最大容量(字节为单位,默觉得10M)
- (void)setDiskCapacity:(NSUInteger)diskC
(4)硬盘缓存的位置:
沙盒/Library/Caches
(5)取得某个请求的缓存
- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)
(6)清除某个请求的缓存
- (void)removeCachedResponseForRequest:(NSURLRequest *)
(7)清除全部的缓存
- (void)removeAllCachedR
缓存GET请求
要想对某个GET请求进行数据缓存。很easy
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 设置缓存策略
request.cachePolicy = NSURLRequestReturnCacheDataElseL
仅仅要设置了缓存策略,系统会自己主动利用NSURLCache进行数据缓存
7种缓存策略
? NSURLRequestUseProtocolCachePolicy // 默认的缓存策略(取决于协议)
? NSURLRequestReloadIgnoringLocalCacheData // 忽略缓存。又一次请求
? NSURLRequestReturnCacheDataElseLoad// 有缓存就用缓存。没有缓存就又一次请求
? NSURLRequestReturnCacheDataDontLoad// 有缓存就用缓存,没有缓存就不发请求。当做请求出错处理(用于离线模式)
NSURLRequestReloadIgnoringLocalAndRemoteCacheData // 未实现
NSURLRequestReloadRevalidatingCacheData // 未实现
NSURLRequestReloadIgnoringLocalAndRemoteCacheData // 未实现
缓存的注意事项
缓存的设置须要根据详细的情况考虑,假设请求某个URL的返回数据:
(1)常常更新:不能用缓存!比方股票、彩票数据
(2)一成不变:果断用缓存
(3)偶尔更新:能够定期更改缓存策略 或者 清除缓存
提示:假设大量使用缓存。会越积越大,建议定期清除缓存
在appDelegate中设置网络缓存大小
实现get 缓存:
假设从server载入数据,通过etag 推断载入数据与缓存是否同样
从本地载入数据
#import "AppDelegate.h"
@interface AppDelegate ()
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
内存缓存-&4M
磁盘缓存-&20M
diskPath 假设是 nil,会缓存到 cached 的 bundleId 目录下
仅仅要在 AppDelegate 中添加下面两句话,今后全部的缓存处理,就不须要管了!
NSURLCache *cathe = [[NSURLCache alloc] initWithMemoryCapacity:4*1024*1024 diskCapacity:20*1024*1024 diskPath:nil];
[NSURLCache setSharedURLCache:cathe];
SDWebImage 的缓存
1. 缓存时间:1周
2. 处理缓存文件。监听系统退出到后台的事件
- 遍历缓存目录。删除全部过期的文件
- 继续遍历缓存目录,将最大的文件删除。一直删除到缓存文件的大小和指定的“磁盘限额”一致。停止
return YES;
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, weak) IBOutlet UIImageView *iconV
@property (nonatomic, copy) NSString *
- (void)removeAllCachedR
@implementation ViewController
- (void)viewDidLoad
[super viewDidLoad];
1. 请求的缓存策略使用 &NSURLRequestReloadIgnoringCacheData&,忽略本地缓存
2. server响应结束后。要记录 Etag,server内容和本地缓存对照是否变化的重要根据!
3. 在发送请求时。设置 If-None-Match,而且传入 etag
4. 连接结束后,要推断响应头的状态码。假设是 304,说明本地缓存内容没有发生变化
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
NSURL *url = [NSURL URLWithString:@"http://mrsunday.local/ml.png"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0];
*设置请求头-&全部的请求头都是通过这样的方法设置的
*假设etag length不为0,说明已经有缓存了
if (self.etag.length & 0)
NSLog(@"设置 etag: %@", self.etag);
[request setValue:self.etag forHTTPHeaderField:@"IF-None-Match"];
NSLog(@"%@",request.HTTPMethod);
*Etag = "\"4a0b9-514a2d804bd40\"";
*能够在请求中添加一个 etag 跟server返回的 etag 进行对照
*就能够推断server相应的资源是否发生变化,详细更新的时间,由request自行处理
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)
*allHeaderFields 全部相应头子端
NSLog(@"%@ %@", httpResponse.allHeaderFields, httpResponse);
*假设server的状态码是304。说明数据已经被缓存,server不再须要返回数据
*须要从本地缓存获取被缓存的数据
if (httpResponse.statusCode == 304)
NSLog(@"load local database");
*针对http訪问的一个缓存类,提供了一个单例
*拿到被缓存的响应
NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
self.iconView.image = [UIImage imageWithData:cachedResponse.data];
self.etag = httpResponse.allHeaderFields[@"etag"];
self.iconView.image = [UIImage imageWithData:data];
- (void)removeAllCachedResponses
[self removeAllCachedResponses];
&&国之画&&&& &&
版权所有 京ICP备号-2
迷上了代码!

我要回帖

更多关于 nsurlprotocol https 的文章

 

随机推荐