URL加載系統(tǒng)之五:緩存、Cookies與協(xié)議

緩存

URL加載系統(tǒng)為請求提供了基于磁盤和內(nèi)存的組合響應(yīng)緩存。這個(gè)緩存讓應(yīng)用減少了對網(wǎng)絡(luò)連接的依賴,提高了性能。

一個(gè)NSURLRequest實(shí)例通過設(shè)置緩存策略來指定本地緩存。默認(rèn)的緩存策略是NSURLRequestUseProtocolCachePolicy,其行為是由協(xié)議指定的針對該協(xié)議最好的實(shí)現(xiàn)方式。另外幾種緩存策略描述如下:

NSURLRequestReloadIgnoringCacheData:URL加載系統(tǒng)將從服務(wù)端加載數(shù)據(jù),而完全忽略緩存。

NSURLRequestReturnCacheDataElseLoad:URL加載系統(tǒng)使用緩存數(shù)據(jù),忽略其過期時(shí)間;只有在沒有緩存版本的時(shí)候才從源端加載數(shù)據(jù)。

NSURLRequestReturnCacheDataDontLoad:允許應(yīng)用指定只有在緩存中的數(shù)據(jù)應(yīng)該被返回。如果在創(chuàng)建NSURLConnection或NSURLDownload實(shí)例時(shí)使用這個(gè)緩存策略,如果響應(yīng)沒有在本地緩存中,則直接返回nil。這類似于使用離線模式,且從來不進(jìn)行網(wǎng)絡(luò)連接。

需要注意的是,目前只有HTTP和HTTPS的響應(yīng)還被緩存。

緩存最常用的場景是使用HTTP協(xié)議做網(wǎng)絡(luò)請求,同時(shí)設(shè)置緩存策略為NSURLRequestUseProtocolCachePolicy。如果一個(gè)請求的NSCachedURLResponse不存在,則加載系統(tǒng)會(huì)從源端獲取數(shù)據(jù)。如果請求的緩存響應(yīng)存在于本地,則URL加載系統(tǒng)檢查響應(yīng)來確定它指定的內(nèi)容必須被重新驗(yàn)證。如果內(nèi)容必須驗(yàn)證,則加載系統(tǒng)發(fā)出一個(gè)HEAD請求到源端以確定資源是否已經(jīng)改變。如果沒有改變,則URL加載系統(tǒng)返回緩存響應(yīng)對象。如果已經(jīng)改變了,則URL加載系統(tǒng)從源端獲取數(shù)據(jù)。

如果緩存響應(yīng)對象沒有指定內(nèi)容必須被重新驗(yàn)證,則加載系統(tǒng)校驗(yàn)緩存響應(yīng)對象的最大age或有效時(shí)間。如果緩存對象未過期,則加載系統(tǒng)返回緩存對象。如果響應(yīng)過舊,則URL加載系統(tǒng)發(fā)起一個(gè)HEAD請求到源端查看資源是否已被修改。如果修改了,則URL加載系統(tǒng)從源端獲取新的數(shù)據(jù)。否則,返回緩存響應(yīng)對象。

默認(rèn)情況下,連接的數(shù)據(jù)基于請求的緩存策略來進(jìn)行緩存,同時(shí)由處理請求的NSURLProtocol子類來解析。如果我們需要對緩存做更精確的控制,我們可以實(shí)現(xiàn)一些代理方法來允許應(yīng)用來確定請求是否應(yīng)該緩存:

對于NSURLSession數(shù)據(jù)和上傳任務(wù),實(shí)現(xiàn)URLSession:dataTask:willCacheResponse:completionHandler:方法。這個(gè)代理方法只用于數(shù)據(jù)請求和上傳任務(wù)。而下載任務(wù)的緩存由指定的緩存策略來決定。

對于NSURLConnection,實(shí)現(xiàn)connection:willCacheResponse:方法

對于NSURLSession,我們的代理方法調(diào)用一個(gè)完成處理器block來告知會(huì)話需要緩存什么東西。對于NSURLConnection,代理方法返回連接需要緩存的對象。不管是哪種情況,代理都會(huì)提供以下值之一:

允許緩存的響應(yīng)對象

新創(chuàng)建的響應(yīng)對象,用于緩存被修改的響應(yīng)

NULL,以阻止緩存

代理方法也可以提供與NSCacheURLResponse對象相關(guān)的userInfo字典,將這些對象作為響應(yīng)的一部分存儲(chǔ)在緩存中。

需要注意的是,如果我們使用NSURLSession眀實(shí)現(xiàn)了代理方法,則代理方法必須總是調(diào)用提供的完成處理器,否則會(huì)導(dǎo)致內(nèi)存泄露。

Cookies

由于HTTP協(xié)議是無狀態(tài)的,客戶端通常使用cookie來提供URL請求間數(shù)據(jù)的持久化存儲(chǔ)。URL加載系統(tǒng)提供接口來創(chuàng)建和管理cookie,將cookie作為HTTP請求的一部分進(jìn)行發(fā)送,并在解析一個(gè)服務(wù)端的響應(yīng)時(shí)獲取cookie。

NSHTTPCookie類封裝了一個(gè)cookie,并提供了大量訪問器來訪問cookie的各種屬性。該類同樣提供了方法用于HTTP cookie頭與NSHTTPCookie實(shí)例之間的互轉(zhuǎn)。URL加載系統(tǒng)自動(dòng)發(fā)送與NSURLRequest對象匹配的任何存儲(chǔ)的cookie,除非該請求指明不需要發(fā)送cookie。同樣,NSURLResponse對象是返回的cookie將根據(jù)當(dāng)前設(shè)定的cookie接收策略來處理。

NSHTTPCookieStorage提供接口來管理NSHTTPCookie對象的集合。與MacOS不同的是,iOS的cookie不能在應(yīng)用間共享。NSHTTPCookieStorage允許一個(gè)應(yīng)用指定cookie接收策略。

協(xié)議支持

URL加載系統(tǒng)允許客戶端程序擴(kuò)展協(xié)議,以支持自定義的傳輸數(shù)據(jù)的方式。URL加載系統(tǒng)默認(rèn)只支持http, https, file, ftp和data協(xié)議。

我們可以繼承NSURLProtocol來實(shí)現(xiàn)一個(gè)自定義的協(xié)議,然后使用NSURLProtocol類的的registerClass:方法將其注冊到URL加載系統(tǒng)中。當(dāng)NSURLSession, NSURLConnection和NSURLDownload對象初始化一個(gè)NSURLRequest的連接時(shí),URL加載系統(tǒng)以注冊順序的倒序來查詢每一個(gè)注冊類。每個(gè)類都將調(diào)用canInitWithRequest:方法,第一個(gè)返回YES的類將被用于處理請求。

如果自定義協(xié)議需要額外的屬性業(yè)支持請求與響應(yīng),則通過創(chuàng)建NSURLRequest, NSMutableRequest和NSResponse類的類別來提供這些屬性的訪問器。NSURLProtocol類提供方法在這些訪問器中設(shè)置和獲取屬性值。

URL加載系統(tǒng)負(fù)責(zé)在連接開始和完成時(shí)創(chuàng)建和釋放NSURLProtocol實(shí)例。我們的應(yīng)用不應(yīng)該直接創(chuàng)建NSURLProtocol的實(shí)例。

當(dāng)NSURLProtocol子類通過URL加載系統(tǒng)初始化時(shí),它提供了一個(gè)實(shí)現(xiàn)NSURLProtocolClient協(xié)議的客戶端對象。NSURLProtocol子類將消息從NSURLProtocolClient協(xié)議發(fā)送到客戶端對象,來告訴URL加載系統(tǒng)它創(chuàng)建了響應(yīng),接收數(shù)據(jù),重定向到新的URL,請求認(rèn)證,完成加載等操作。如果自定義協(xié)議支持認(rèn)證,還必須實(shí)現(xiàn)NSURLAuthenticationChallengeSender協(xié)議。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,340評論 11 349
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,837評論 18 139
  • iOS網(wǎng)絡(luò)編程讀書筆記 Facade Tester客戶端門面模式的實(shí)例(被動(dòng)版本化) 被動(dòng)版本化,所以硬編碼URL...
    melouverrr閱讀 1,619評論 3 7
  • 概覽 緩存組件應(yīng)該說是每個(gè)客戶端程序必備的核心組件,試想對于每個(gè)界面的訪問都必須重新請求勢必降低用戶體驗(yàn)。但是如何...
    默默_David閱讀 1,959評論 1 9
  • 如果說人生是一部戲,那么愛情就是其中最絢麗的音調(diào),《歡樂頌》之愛情,更耐人品味。 不離不棄的愛情 安迪,一個(gè)高智商...
    風(fēng)中藍(lán)荷閱讀 833評論 6 5