理解缓存访问 <- URL会话编程指南

URL加载系统为请求的响应提供内存与磁盘复合的缓存。该缓存允许应用程序减少对网络连接的依赖,并增加它的性能。

为请求使用缓存

NSURLRequest实例通过设置缓存策略来指定本地缓存的使用方式。缓存策略可以通过为NSURLRequestCachePolicy设置以下值来得到:NSURLRequestUseProtocolCachePolicy, NSURLRequestReloadIgnoringCacheData, NSURLRequestReturnCacheDataElseLoad, 或 NSURLRequestReturnCacheDataDontLoad.

NSURLRequest实例的默认缓存策略是NSURLRequestUseProtocolCachePolicy。NSURLRequestUseProtocolCachePolicy行为是特定于协议的,并且被定义为协议最合适的策略。

将缓存策略设置为NSURLRequestReloadIgnoringCacheData,会导致URL加载系统从原始资源加载数据,而忽略以完成的缓存。

NSURLRequestReturnCacheDataElseLoad缓存策略会导致URL加载系统使用缓存数据,却忽略这个缓存是否陈旧。当且仅当没有缓存数据时,URL加载系统会从原始资源处加载数据。

NSURLRequestReturnCacheDataDontLoad策略允许应用程序指定缓存可以返回的唯一数据。尝试使用缓存机制创建一个NSURLSessionTask实例,如果响应不是在本地缓存中,立即返回nil。这在功能上和“离线”模式类似,并且不产生网络连接。

注意:当前,只有对HTTP和HTTPS请求的响应才会被缓存。FTP和file协议尝试访问缓存策略允许的原始资源。自定义NSURLProtocol类可以选择性的提供缓存。

缓存使用HTTP协议语义

最复杂的缓存使用情况,是当请求使用HTTP协议,并且设置NSURLRequestUseProtocolCachePolicy为缓存策略。

如果请求没有NSCachedURLResponse,则URL加载系统会从原始资源获取数据。

如果请求存在缓存的响应,URL加载系统会检查该响应,以确定是否它所指定的内容必须要重新验证。

如果该内容需要重新验证,URL加载系统会制作原始资源的HEAD请求,用来查看该资源是否已经改变。如果它没有改变,URL加载系统就返回缓存的响应。如果它已经改变,URL加载系统会从原始资源处获取数据。

如果缓存的响应没有指定内容必须重新验证,URL加载系统检查指定缓存的响应的有效期。如果缓存的响应是近期的,则URL加载系统返回缓存的响应。如果响应过期了,URL加载系统会制作原始资源的HEAD请求,用来查看该资源是否已经改变。如果它没有改变,URL加载系统就返回缓存的响应。否则它会从原始资源处获取数据。

RFC 2616第13节(http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13
详细说明了涉及的语义。

以编码方式控制缓存

默认情况下,请求的数据会基于请求的缓存策略被缓存起来,由处理该请求的NSURLProtocol子类解读(interpreted)。

如果app需要对缓存进行更多精确的编程控制(如果该协议支持缓存),你可以实现委托方法,该方法允许app根据每个请求确定是否缓存特定的响应。

对于NSURLSession数据和上传任务,请实现URLSession:dataTask:willCacheResponse:completionHandler:方法。该委托方法只有在数据和上传任务的时候被调用。下载任务的缓存策略由特定的缓存策略决定。

对于NSURLSession,你的委托方法通过调用完成处理程序代码块告诉会话要缓存的内容。委托通常提供下列值中的一个:

  • 提供响应对象来允许缓存
  • 最新创见的响应对象来缓存修改的响应——例如,使用存储策略的响应允许缓存到内存而不是磁盘
  • nil用来防止缓存

你的委托方法还能向与NSCachedURLResponse对象相关的userInfo字典插入对象,从而将这些对象作为响应的一部分存储到缓存中。

重要:你的委托方法必须始终调用完成处理程序。否则,app会泄露内存。

代码清单5-1的示例阻止HTTPS响应的磁盘缓存。它还把当前日期添加到响应的缓存的用户信息字典中。

代码清单 5-1 URLSession:dataTask:willCacheResponse:completionHandler: 实现示例

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask

 willCacheResponse:(NSCachedURLResponse *)proposedResponse

 completionHandler:(void (^)(NSCachedURLResponse * __nullable cachedResponse))completionHandler {

    NSCachedURLResponse *newCachedResponse = proposedResponse;

    NSDictionary *newUserInfo;

    newUserInfo = [NSDictionary dictionaryWithObject:[NSDate date]

                                              forKey:@"Cached Date"];

    if ([proposedResponse.response.URL.scheme isEqualToString:@"https"]) {

#if ALLOW_IN_MEMORY_CACHING

        newCachedResponse = [[NSCachedURLResponse alloc]

                             initWithResponse:proposedResponse.response

                             data:proposedResponse.data

                             userInfo:newUserInfo

                             storagePolicy:NSURLCacheStorageAllowedInMemoryOnly];

#else // !ALLOW_IN_MEMORY_CACHING

        newCachedResponse = nil;

#endif // ALLOW_IN_MEMORY_CACHING

    } else {

        newCachedResponse = [[NSCachedURLResponse alloc]

                             initWithResponse:[proposedResponse response]

                             data:[proposedResponse data]

                             userInfo:newUserInfo

                             storagePolicy:[proposedResponse storagePolicy]];

    }

 

    completionHandler(newCachedResponse);

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,566评论 18 139
  • 概览 缓存组件应该说是每个客户端程序必备的核心组件,试想对于每个界面的访问都必须重新请求势必降低用户体验。但是如何...
    默默_David阅读 1,902评论 1 9
  • 本指南描述了Foundation框架的一些类,它们可用于与URL交互,也可以与使用标准网络协议的服务器进行通信。这...
    raingu24阅读 323评论 0 2
  • iOS网络编程读书笔记 Facade Tester客户端门面模式的实例(被动版本化) 被动版本化,所以硬编码URL...
    melouverrr阅读 1,597评论 3 7
  • 习惯是一种日常 坚持某件事也会渐渐的变成习惯 我说不出自己有那些习惯 但总会有某些事常常去做 别人问起,就会说,我...
    念时光z阅读 162评论 0 0