iOS网络缓存

<div id="article_content" class="article_content">


<p><span style="font-size:14px">参考:<a target="_blank" href="https://github.com/ChenYilong/ParseSourceCodeStudy/blob/master/02_Parse的网络缓存与离线存储/iOS网络缓存扫盲篇.md">https://github.com/ChenYilong/ParseSourceCodeStudy/blob/master/02_Parse的网络缓存与离线存储/iOS网络缓存扫盲篇.md</a></span></p>
<p></p>
<h2 style="margin-top:1em; margin-bottom:16px; line-height:1.225; font-size:1.75em; padding-bottom:0.3em; border-bottom-width:1px; border-bottom-style:solid; border-bottom-color:rgb(238,238,238); color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'"><a name="t0"></a>
GET网络请求缓存</h2>
<span style="color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">首先要知道,POST请求不能被缓存,只有 GET 请求能被缓存。因为从数学的角度来讲,GET 的结果是&nbsp;</span><code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace; font-size:14px; padding:0.2em 0px; margin:0px; color:rgb(51,51,51)">幂等</code><span style="color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">&nbsp;的,就好像字典里的
 key 与 value 就是</span><code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace; font-size:14px; padding:0.2em 0px; margin:0px; color:rgb(51,51,51)">幂等</code><span style="color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">的,而
 POST 不&nbsp;</span><code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace; font-size:14px; padding:0.2em 0px; margin:0px; color:rgb(51,51,51)">幂等</code><span style="color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">&nbsp;。缓存的思路就是将查询的参数组成的值作为
 key ,对应结果作为value。从这个意义上说,一个文件的资源链接,也叫 GET 请求,下文也会这样看待。</span><br>
<p></p>
<p><span style="color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px"></span></p>
<h3 style="margin-top:1em; margin-bottom:16px; line-height:1.43; font-size:1.5em; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'"><a name="t1"></a>
80%的缓存需求:两行代码就可满足</h3>
<p></p>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
设置缓存只需要三个步骤:</p>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
第一个步骤:请使用 GET 请求。</p>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
第二个步骤:</p>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
如果你已经使用 了 GET 请求,<a href="http://lib.youkuaiyun.com/base/ios" class="replace_word" title="iOS知识库" target="_blank" style="color:#df3434; font-weight:bold;">iOS</a> 系统 SDK 已经帮你做好了缓存。你需要的仅仅是设置下内存缓存大小、磁盘缓存大小、以及缓存路径。甚至这两行代码不设置也是可以的,会有一个默认值。代码如下:</p>
<div class="dp-highlighter bg_objc"><div class="bar"><div class="tools"><b>[objc]</b> <a href="#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 515px; top: 985px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_1" src="http://static.blog.youkuaiyun.com/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_1" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=1&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a><span class="tracking-ad" data-mod="popu_167"><a href="https://code.youkuaiyun.com/snippets/1561646" target="_blank" title="在CODE上查看代码片" style="text-indent:0;"><img src="https://code.youkuaiyun.com/assets/CODE_ico.png" width="12" height="12" alt="在CODE上查看代码片" style="position:relative;top:1px;left:2px;"></a></span><span class="tracking-ad" data-mod="popu_170"><a href="https://code.youkuaiyun.com/snippets/1561646/fork" target="_blank" title="派生到我的代码片" style="text-indent:0;"><img src="https://code.youkuaiyun.com/assets/ico_fork.svg" width="12" height="12" alt="派生到我的代码片" style="position:relative;top:2px;left:2px;"></a></span></div></div><ol start="1" class="dp-objc"><li class="alt"><span><span class="keyword">NSURLCache</span><span>&nbsp;*urlCache&nbsp;=&nbsp;[[NSURLCache</span><span class="vars">&nbsp;alloc</span><span>]</span><span class="vars">&nbsp;initWithMemoryCapacity</span><span>:</span><span class="xcodenumber">4</span><span class="keyword">4</span><span>&nbsp;*&nbsp;</span><span class="xcodenumber">1</span><span class="keyword">1024</span><span>&nbsp;*&nbsp;</span><span class="xcodenumber">1</span><span class="xcodenumber">0</span><span class="xcodenumber">2</span><span class="xcodenumber">4</span><span class="vars">&nbsp;diskCapacity</span><span>:</span><span class="xcodenumber">2</span><span class="keyword">20</span><span>&nbsp;*&nbsp;</span><span class="xcodenumber">1</span><span class="keyword">1024</span><span>&nbsp;*&nbsp;</span><span class="xcodenumber">1</span><span class="xcodenumber">0</span><span class="xcodenumber">2</span><span class="xcodenumber">4</span><span class="vars">&nbsp;diskPath</span><span class="keyword">:nil</span><span>];&nbsp;&nbsp;</span></span></li><li class=""><span>[NSURLCache<span class="vars">&nbsp;setSharedURLCache</span><span>:urlCache];&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.youkuaiyun.com/images/save_snippets_01.png"></a></div></div><pre code_snippet_id="1561646" snippet_file_name="blog_20160121_1_942515" name="code" class="objc" style="display: none;">NSURLCache *urlCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil];
[NSURLCache setSharedURLCache:urlCache];</pre><br>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
第三个步骤:没有第三步!</p>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
你只要设置了这两行代码,基本就可满足80%的缓存需求。AFNetworking 的作者 Mattt曾经说过:</p>
<blockquote style="margin:0px 0px 16px; padding:0px 15px; color:rgb(119,119,119); border-left-width:4px; border-left-style:solid; border-left-color:rgb(221,221,221); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
<p style="margin-top:0px; margin-bottom:0px">无数开发者尝试自己做一个简陋而脆弱的系统来实现网络缓存的功能,殊不知&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace; font-size:14px; padding:0.2em 0px; margin:0px">NSURLCache</code>&nbsp;只要两行代码就能搞定且好上 100 倍。</p>
</blockquote>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
(AFN 是不是在暗讽 SDWebImage 复杂又蹩脚的缓存机制??)</p>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
要注意</p>
<ul style="padding:0px 0px 0px 2em; margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
<li style="">iOS 5.0开始,支持磁盘缓存,但仅支持 HTTP</li><li style="">iOS 6.0开始,支持 HTTPS 缓存</li></ul>
<h3 style="margin-top:1em; margin-bottom:16px; line-height:1.43; font-size:1.5em; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'"><a name="t2"></a>
控制缓存的有效性</h3>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
我们知道:</p>
<ul style="padding:0px 0px 0px 2em; margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
<li style="">只要是缓存,总会过期。</li></ul>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
那么缓存的过期时间如何控制?</p>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
上文中的两行代码,已经给出了一个方法,指定超时时间。但这并也许不能满足我们的需求,如果我们对数据的一致性,时效性要求很高,即使1秒钟后数据更改了,客户端也必须展示更改后的数据。这种情况如何处理?</p>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
下面我们将对这种需求,进行解决方案的介绍。顺序是这样的:先从文件类型的缓存入手,引入两个概念。然后再谈下,一般数据类型比如 JSON 返回值的缓存处理。</p>
<h3 style="margin-top:1em; margin-bottom:16px; line-height:1.43; font-size:1.5em; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'"><a name="t3"></a>
文件缓存:借助ETag或Last-Modified判断文件缓存是否有效</h3>
<h4 style="margin-top:1em; margin-bottom:16px; line-height:1.4; font-size:1.25em; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'"><a name="t4"></a>
<a target="_blank" id="user-content-last-modified" class="anchor" href="https://github.com/ChenYilong/ParseSourceCodeStudy/blob/master/02_Parse%E7%9A%84%E7%BD%91%E7%BB%9C%E7%BC%93%E5%AD%98%E4%B8%8E%E7%A6%BB%E7%BA%BF%E5%AD%98%E5%82%A8/iOS%E7%BD%91%E7%BB%9C%E7%BC%93%E5%AD%98%E6%89%AB%E7%9B%B2%E7%AF%87.md#last-modified" style="background-color:transparent; color:rgb(64,120,192); text-decoration:none; display:inline-block; padding-right:2px; margin-left:-18px; line-height:1.2"><span class="octicon octicon-link" style=""></span></a>Last-Modified</h4>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
服务器的文件存贮,大多采用资源变动后就重新生成一个链接的做法。而且如果你的文件存储采用的是第三方的服务,比如七牛、青云等服务,则一定是如此。</p>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
这种做法虽然是推荐做法,但同时也不排除不同文件使用同一个链接。那么如果服务端的file更改了,本地已经有了缓存。如何更新缓存?</p>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
这种情况下需要借助&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace; font-size:14px; padding:0.2em 0px; margin:0px">ETag</code>&nbsp;或&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace; font-size:14px; padding:0.2em 0px; margin:0px">Last-Modified</code>&nbsp;判断图片缓存是否有效。</p>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace; font-size:14px; padding:0.2em 0px; margin:0px">Last-Modified</code>&nbsp;顾名思义,是资源最后修改的时间戳,往往与缓存时间进行对比来判断缓存是否过期。</p>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文件在服务期端最后被修改的时间,格式类似这样:</p>
<div class="highlight highlight-source-objc" style="margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
<pre style="overflow:auto; font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace; font-size:14px; margin-top:0px; margin-bottom:0px; line-height:1.45; padding:16px; background-color:rgb(247,247,247); word-wrap:normal; word-break:normal">        Last-Modified: Fri, <span class="pl-c1" style="color:rgb(0,134,179)">12</span> May <span class="pl-c1" style="color:rgb(0,134,179)">2006</span> <span class="pl-c1" style="color:rgb(0,134,179)">18</span>:<span class="pl-c1" style="color:rgb(0,134,179)">53</span>:<span class="pl-c1" style="color:rgb(0,134,179)">33</span> GMT</pre>
</div>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
客户端第二次请求此URL时,根据 HTTP 协议的规定,浏览器会向服务器传送 If-Modified-Since 报头,询问该时间之后文件是否有被修改过:</p>
<div class="highlight highlight-source-objc" style="margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
<pre style="overflow:auto; font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace; font-size:14px; margin-top:0px; margin-bottom:0px; line-height:1.45; padding:16px; background-color:rgb(247,247,247); word-wrap:normal; word-break:normal">        If-Modified-Since: Fri, <span class="pl-c1" style="color:rgb(0,134,179)">12</span> May <span class="pl-c1" style="color:rgb(0,134,179)">2006</span> <span class="pl-c1" style="color:rgb(0,134,179)">18</span>:<span class="pl-c1" style="color:rgb(0,134,179)">53</span>:<span class="pl-c1" style="color:rgb(0,134,179)">33</span> GMT</pre>
</div>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
总结下来它的结构如下:</p>
<table style="border-collapse:collapse; border-spacing:0px; margin-top:0px; margin-bottom:16px; display:block; width:888px; overflow:auto; word-break:normal; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
<thead style="">
<tr style="border-top-width:1px; border-top-style:solid; border-top-color:rgb(204,204,204)">
<th style="padding:6px 13px; border:1px solid rgb(221,221,221)">请求 HeaderValue</th>
<th style="padding:6px 13px; border:1px solid rgb(221,221,221)">响应 HeaderValue</th>
</tr>
</thead>
<tbody style="">
<tr style="border-top-width:1px; border-top-style:solid; border-top-color:rgb(204,204,204)">
<td style="padding:6px 13px; border:1px solid rgb(221,221,221)">Last-Modified</td>
<td style="padding:6px 13px; border:1px solid rgb(221,221,221)">If-Modified-Since</td>
</tr>
</tbody>
</table>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
如果服务器端的资源没有变化,则自动返回 HTTP 304 (Not Changed.)状态码,内容为空,这样就节省了传输数据量。当服务器端代码发生改变或者重启服务器时,则重新发出资源,返回和第一次请求时类似。从而保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。</p>
<span style="color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">判断方法用伪代码表示:</span><br>
<p><span style="color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px"><span style="color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px"></span></span></p><div class="dp-highlighter bg_objc"><div class="bar"><div class="tools"><b>[objc]</b> <a href="#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 515px; top: 2624px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_2" src="http://static.blog.youkuaiyun.com/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_2" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=2&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a><span class="tracking-ad" data-mod="popu_167"><a href="https://code.youkuaiyun.com/snippets/1561646" target="_blank" title="在CODE上查看代码片" style="text-indent:0;"><img src="https://code.youkuaiyun.com/assets/CODE_ico.png" width="12" height="12" alt="在CODE上查看代码片" style="position:relative;top:1px;left:2px;"></a></span><span class="tracking-ad" data-mod="popu_170"><a href="https://code.youkuaiyun.com/snippets/1561646/fork" target="_blank" title="派生到我的代码片" style="text-indent:0;"><img src="https://code.youkuaiyun.com/assets/ico_fork.svg" width="12" height="12" alt="派生到我的代码片" style="position:relative;top:2px;left:2px;"></a></span></div></div><ol start="1" class="dp-objc"><li class="alt"><span><span class="keyword">if</span><span>&nbsp;ETagFromServer&nbsp;!=&nbsp;ETagOnClient&nbsp;||&nbsp;LastModifiedFromServer&nbsp;!=&nbsp;LastModifiedOnClient&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;GetFromServer&nbsp;&nbsp;</span></li><li class="alt"><span><span class="keyword">else</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;GetFromCache&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.youkuaiyun.com/images/save_snippets.png"></a></div></div><pre code_snippet_id="1561646" snippet_file_name="blog_20160121_2_8717667" name="code" class="objc" style="display: none;">if ETagFromServer != ETagOnClient || LastModifiedFromServer != LastModifiedOnClient
   GetFromServer
else
   GetFromCache</pre><br>
<span style="color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">之所以使用</span><br>
<p></p>
<p><span style="color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px"><span style="color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px"><span style="color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px"></span></span></span></p>
<pre style="overflow:auto; font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace; font-size:14px; margin-top:0px; margin-bottom:0px; line-height:1.45; padding:16px; background-color:rgb(247,247,247); word-wrap:normal; word-break:normal; color:rgb(51,51,51)">LastModifiedFromServer != LastModifiedOnClient</pre>
<p></p>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
而非使用:</p>
<div class="highlight highlight-source-objc" style="margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
<pre style="overflow:auto; font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace; font-size:14px; margin-top:0px; margin-bottom:0px; line-height:1.45; padding:16px; background-color:rgb(247,247,247); word-wrap:normal; word-break:normal">LastModifiedFromServer &gt; LastModifiedOnClient</pre>
</div>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
原因是考虑到可能出现类似下面的情况:服务端可能对资源文件,废除其新版,回滚启用旧版本,此时的情况是:</p>
<div class="highlight highlight-source-objc" style="margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
<pre style="overflow:auto; font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace; font-size:14px; margin-top:0px; margin-bottom:0px; line-height:1.45; padding:16px; background-color:rgb(247,247,247); word-wrap:normal; word-break:normal">LastModifiedFromServer &lt;= LastModifiedOnClient</pre>
</div>
<p style="margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'; font-size:16px; line-height:25px">
但我们依然要更新本地缓存。</p>
。。。。。。。。。
   
</div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值