7.2.3 避免网络请求

IETF 在 RFC 2616 中明确定义了 Web 浏览器与 Web 服务器之间的 HTTP 缓存的工作方式, 可以在 http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html 上找到相关信息. HTTP 被设计为针对浏览器与服务器之间的通信, 缓存机制也是针对这种使用模式的. iOS 提供了一种机制来利用标准 HTTP 缓存, 以及采取相应的行为. 通过 NSURLRequest 发出的每个请求都会经过缓存组件. 该组件是 NSURLCache 或其子类的实例. 这个对象是 iOS 采用的管理来自服务器的响应缓存的标准机制

1. 默认缓存行为

在默认情况下, NSURLRequest 遵照 RFC 2616 来管理缓存. 该默认行为指定缓存要返回大多数当前的内容副本. 如果返回的内容不是最新的, 就会发出警告; 如果无法返回内容, 则报告错误

在 iOS 上, 这意味着只有在响应头表明响应能够缓存的情况下, 当第一次返回时才会将其缓存到内存中. 对于后续发送给相同 URL 的请求来说, iOS 会使用 If-Modified-Since 头(包含缓存响应的修改日期与时间)向服务器发送请求. 如果服务器确定自从请求头提供的时间开始内容没有被修改, 就会返回状态为 304 的响应, 并且没有响应体. 通过这个响应, iOS 能够确定它所缓存的副本是最新的内容, 并使用 200 状态码返回, 这很有效地对应用代码隐藏了缓存活动. 在内容来自于内容分发网络(CDN)的网络配置中, 源 URL 对于不同的请求来说可能是不同的, 因此对于 HTTP 标准定义的缓存机制是不适用的

这些标准的缓存规则的设计专门针对与 Web 浏览器的交互. 使用 HTTP 作为传输协议的移动应用可以适当修改这些规则来改进性能并满足应用的需求. iOS 中的 URL 加载系统向客户端应用提供了一种方式来覆写默认行为. 在覆写默认行为时, 你需要花一些时间来充分理解可能会导致应用出现缺陷的边际行为

可以通过为请求设定缓存策略来覆写默认的缓存规则

设定缓存策略

iOS 提供了 6 种不同的设置, 使得开发者能够控制响应缓存的方式:

- NSURLRequestUseProtocolCachePolicy - 该设置告诉系统遵照 RFC 2616 指定的规则

- NSURLRequestReloadIgnoringLocalCacheData - 该设置告诉请求略过本地缓存, 从网络上检索新的内容. 如果某些网络设备(如缓存网络代理)介于应用与数据源之间, 并且持有内容的缓存副本, 就会返回缓存副本

- NSURLRequestReloadIgnoringLocalAndRemoteCacheData - 该设置告诉请求略过本地缓存并将头添加到请求中, 同时告诉中间设备也略过缓存, 提供源服务器上的最新数据

- NSURLRequestReturnCacheDataElseLoad - 该设置会让缓存系统返回一份内容的缓存副本而不去验证服务器上是否有最新的副本. 如果请求的缓存副本在缓存中存在, 就会将其返回. 如果缓存副本不存在, 那就通过网络请求检索内容. 该设置提供了最快的响应时间, 但却最有可能返回过期的数据. 要想通过该设置带来收益, 请使用该类型的请求向用户提供最初的快速响应, 然后在后台线程中发出请求, 使用服务器的最新数据来刷新缓存

- NSURLRequestReturnCacheDataDontLoad - 该设置指定只返回缓存中的内容. 如果内容不在缓存中, 那就会返回错误而不是从服务器上获取内容

- NSURLRequestReloadRevalidatingCacheData - 该设置总是会重新验证数据. 在某些情况下, 缓存的响应可能会有过期时间, 到了这个时间后系统就会检查最新的数据. 如果使用该设置, 那就会忽略掉过期时间, 并且总是验证服务器有没有最新的内容

除了配置每个请求使用缓存的方式外, 还可以通过配置应用的 NSURLCache 对象来指定应用所能缓存的数据量

2. 配置 NSURLCache

在应用使用任何标准的 iOS 类创建网络请求时, 系统都会创建 NSURLCache 实例. 在默认情况下, 该实例只会将数据缓存在 RAM 中, 这意味着当程序退出时, 其缓存的请求就会被清空. 当设备处于低内存状态时也会清空 RAM 缓存

iOS 提供了一种方式来重新定义默认的缓存, 并指定了更大的内存容量与持久化存储, 以便缓存在应用重启后依然可以使用.

重新定义的默认缓存

该例创建 1MB 的内存缓存和 20MB 的持久化缓存. 缓存数据库的位置位于应用的沙箱, 在 Library/Caches 目录下, 文件名为 URLCache. 示例代码的第 2 行将应用的缓存实例设定为上一行创建的那一个

iOS 中有一种奇怪的现象, 即在某些情况下, 应用中的系统组件会将缓存的内存容量设为 0MB, 这就禁用了缓存. 解决了这个无法解释的行为的一种方式就是通过自己的实现子类化 NSURLCache, 拒绝将内存缓存大小设为 0. 

子类化 NSURLCache, 拒绝将内存缓存大小设为 0

setMemoryCapacity: 方法中的代码会验证大小不为 0, 并调用父类, 从而将新的大小设为除了 0 之外的其他值

可以通过压缩数据及管理化请求以最大化地提升应用的性能, 不过最快的请求实际上是没有发出的请求. 通过仔细考虑应用需求以及服务器的行为, 可以将数据保留在缓存中, 只有当服务器上的数据发生变化时才刷新, 从而避免发出这些请求

7.3 小结

iOS 用户都希望应用能够立刻响应每个请求. 移动产业有这样一条原则, 即屏幕越小, 用户越没耐心. 提供让用户乐于使用的应用意味着要珍惜用户的时间, 就像珍惜你自己的时间一样. 通过压缩请求与响应来优化应用所使用的带宽, 通过管道化请求避免不必要的延迟, 甚至通过缓存响应来避免冗余的网络请求都会加速应用并改进用户体验

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

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,099评论 18 139
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,612评论 4 59
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,566评论 25 707
  • 今天分享说个简单的事儿,昨儿看papi酱视频,她吐槽自己又成魔兽寡妇了……早晨群里有麻麻玩笑足球寡妇,嘿嘿,对于这...
    和翊浛阅读 211评论 0 0
  • 文案是什么? 文案就是电脑后面的销售员,通过文字的力量来吸引用户产生购买意向。互联网时代的文案需要具备抓住用户痛点...
    12_21阅读 368评论 0 1