對比iOS網路組件:AFNetworking VS ASIHTTPRequest

來源:互聯網
上載者:User

標籤:

對比iOS網路組件:AFNetworking VS ASIHTTPRequest

在開發iOS應用過程中,如何高效的與服務端API進行資料交換,是一個常見問題。一般開發人員都會選擇一個第三方的網路組件作為服務,以提高開發效率和穩定性。這些組件把複雜的網路底層操作封裝成友好的類和方法,並且加入異常處理等。

那麼,大家最常用的組件是什嗎?這些組件是如何提升開發效率和穩定性的?哪一款組件適合自己,是 AFNetworking(AFN)還是 ASIHTTPRequest(ASI)?幾乎每一個iOS互連網應用開發人員都會面對這樣的選擇題,要從這兩個最常用的組件裡選出一個好的還真不是那麼容易。

單單從兩個控制項版本提交的時間節點來看,AFN的第一個提交是2011年的1月1日,那個時候ASI早已是1.8+的版本了;而當AFN發布1.0版,2012年10月份的時候,ASI早早的已經停止更新了。這樣看起來,AFN是ASI的繼任者,似乎不存在之前提到的選擇困難的問題,而事實並非如此。本文將從用法、功能、效能和原理幾個方面對二者進行簡單對比,看看二者之間到底存在著怎樣的區別,到底應該如何選擇。

 

 

1、用法對比

首先,從推薦用法上就可以看出二者設計理念上大有不同。

圖1,AFN的範例程式碼,發起請求(出自:Posts.m)

 

AFN官方推薦的使用方法是,為一系列相關的請求定義一個HTTPClient,共用一個BaseURL。每次請求把URL中除BaseURL的Path部分做為參數傳給HTTPClient的靜態方法,並註冊一個Block用於回調。

圖2,ASI範例程式碼,發起非同步請求(出自:ASIHTTPRequestTests.m)

ASI推薦使用方法就非常傳統,每一個請求都由構造方法初始化一個(共用)執行個體,通過這個執行個體配置參數並發起請求。ASI最初使用delegate模式回調,在iOS SDK支援Block之後也提供了註冊Block的執行個體方法。

以上引用的兩段代碼都出自各自項目的樣本工程。對比兩段代碼可以很清楚的看出,同樣是發起一個最普通的非同步請求,使用AFN只需要調用一個靜態方法,但代碼可讀性較差;而ASI的樣本看起來更清晰,但需要調用多個執行個體方法才能完成一次請求。AFN的設計更加工程化,或者說對使用者更友好,而ASI的設計更經典,典型的OOP。

除了初級用法上的區別,二者的進階功能和對擴充的支援也頗有不同。

2、進階功能

AFN只封裝了一些常用功能,滿足基本需求,而直接忽略了很多擴充功能。例如:AFN預設沒有封裝同步請求,如果開發人員需要使用同步請求,則需要重寫getPath:parameters:success:failure方法,對AFHTTPRequestOperation進行同步處理;而ASI則是直接通過調用一個startSynchronous方法。

此外AFN針對JSON、XML、PList和Image四種資料結構封裝了各自處理器,開發人員可以把處理器註冊到操作隊列中,直接在回調方法中獲得格式化以後的資料。在樣本工程中就使用了JSON處理器:把AFJSONRequestOperation註冊到操作隊列裡。

圖3,AFN範例程式碼,初始化自訂的HTTPClient(出自:AFAppDotNetAPIClient.m)

而ASI在這方面顯得更原始,沒有針對任何資料類型做特別封裝,只是預留了各種介面和工具供開發人員自行擴充。ASI比AFN提供更多擴充功能還有一個原因,它把許多內部用到的功能也抽象成類和方法。例如:

ASIHTTPRequestDataCompressor和ASIHTTPRequestDataDecompressor兩個類,只用於壓縮本地檔案,構造POST Body和解壓縮返回資料,但這兩個類仍然被設計為獨立功能,提供了對多種資料結構進行壓縮和解壓縮的方法。

對比二者的進階功能和對擴充的支援後,可以看出AFN把初級功能(或者叫常用功能)做到了90分。調用方式夠簡單,處理器夠豐富,使用者用起來可以算是輕鬆加愉快。但它放棄了對進階功能的支援,要滿足較複雜的需求,就要大費周折了,在這方面最多隻有40分。而ASI顯然不滿足於做好初級功能,但為了提供更豐富的可擴充介面,導致初級功能用起來也要花上一些力氣。雖然ASI單獨提供了支援Amazon S3和Rackspace Cloud Files的控制項,但對於生在紅旗下的我朝開發人員來說基本沒用,所以在初級功能的支援上ASI能得個70分,犧牲了初級功能的易用性,換來的是良好的擴充性,在進階功能的使用上遠遠好於AFN,也能得個70分。

從使用角度對比過後,基本上對這兩個項目有一個整體上的認識,再深入下去看看二者的效能如何。

3、效能對比

我分別用AFN和ASI進行了測試,測試環境如下:iPhone5,聯通3G訊號全滿,室內靜止狀態,請求國內雙線機房獨立伺服器的靜態檔案,1~20K共20個檔案,每個檔案請求20次,記錄從建立請求到完全下載檔案的耗時,結果如下:

圖4,AFN連續訪問1 ~ 20K檔案耗時

圖5,ASI連續訪問1 ~ 20K檔案耗時

圖4是AFN的記錄圖,綠色為20次請求中耗時最久的一次,藍色為耗時最短的一次,黃色為去除最大值和最小值的18次平均值。從這個圖可以看出,AFN最開始建立對象耗時近2.5秒,隨後穩定下來,在3K、7K、15K和20K時出現了抖動。圖5是ASI做相同測試的結果,首次建立對象近2.25秒,略優於AFN,同樣在5K、11K、13K、14K和16K發生了一些抖動,但抖動幅度似乎小於AFN,可見穩定性更好一些。

下邊是把二者的測試結果放在一起的對比圖,可以更直觀的比較二者的區別。

圖6,ASI和AFN耗時最大值對比

圖6的最大值對比可以更明顯的看出二者的抖動對比,ASI略好一些。

圖7,ASI和AFN耗時最小值對比

圖7的最小值對比可以看出,在每一個大小的測試中ASI的最佳效能似乎都要優於AFN。

圖8,ASI和AFN耗時平均值對比

圖8是耗時平均值的對比,更能夠說明問題。檔案小於12K的測試中ASI的效能優勢並沒有非常明顯,超過12K以後,ASI優勢開始明顯起來,每一次請求都要比AFN節約20% ~ 30%,近0.1秒。同時從這張圖上還可以看出,隨著下載檔案變大,請求耗時並不是線形增長的,這是由於一次請求大部分時間都消耗在建立串連上,而真正接收資料只佔用了極少時間,這個問題不在本篇文章的討論範圍,所以不多說,有興趣的讀者可以移步http://segmentfault.com/t/ios進一步討論。

4、原理分析

ASI的效能似乎全面優於AFN,那下邊從二者的實現原理上看一下到底是什麼原因造成這種差距。ASI基於CFNetwork架構開發,而AFN基於NSURL,底層的區別是導致二者效能差距的重要原因之一。

圖9,ASI和AFN以及底層架構的關係

我們知道所有網路通訊的基礎是Socket,一個Socket與另一個串連並傳送資料。BSD Socket是一類最常見的Socket抽象介面。

Core Foundation架構中的CFSocket就是基於BSD Socket開發的。它幾乎涵蓋了BSD Socket的全部功能,更重要的是把Socket整合到事件的處理迴圈中。Core Founda-tion中較高層的CFStream是基於CFSocket開發的讀寫流支援。

CFNetwork是基於Core Foundation中CFStream的一個底層高效能網路架構,它由提供基礎服務的CFSocketStream,支援HTTP協議的CFHTTP,基於CFHTTP用於身份認證的CFHTTPAuthentication和支援FTP協議的CFFTP組成。

正9所示,ASI是基於CFHTTP開發的一個組件;而AFN的基礎——NSURL,也是基於CFNetwork開發的。也就是說ASI相比AFN更加底層,這就從一定程度上造成二者的效能差距。

另一個方面,雖然二者都使用NSOperation和NSOperationQueue實現但底層的區別也導致實現方式上有非常大的差別。

ASI的直接操作對象ASIHTTPRequest是NSOperation的子類,實現了NSCopying協議。在initialize和initWithURL:方法中初始化相關屬性並配置一系列請求相關參數預設值。此外,ASIHTTPRequest還提供了一系列的執行個體方法用來配置請求對象。在非同步請求的處理上,ASIHTTPRequest對象初始化結束後,在startAsynchronous方法中把對象加入共用操作隊列。此後,包括建立CFHTTPMessageRef,也就是處理網路請求的主要對象(事實上是一個指向__CFHTTPMessage結構的指標),在內的所有操作都在ASIHTTPRequest對象所屬的子線程中完成。

AFN的直接操作對象AFHTTPClient不同於ASI,是一個實現了NSCoding和NSCopying協議的NSObject子類。AFHTTPClient是一個封裝了一系列操作方法的“工具類”,處理請求的操作類是一系列單獨的,基於NSOperation封裝的,AFURLConnectionOperation的子類。AFN的範例程式碼中通過一個靜態方法,使用dispatch_once()的方式建立AFHTTPClient的共用執行個體,這也是官方建議的使用方法。在建立AFHTTPClient的初始化方法中,建立了OperationQueue並設定一系列參數預設值。在getPath:parameters:success:failure方法中建立NSURLRequest,以NSURLRequest對象執行個體作為參數,建立一個NSOperation,並加入在初始化發方中建立的NSOperationQueue。以上操作都是在主線程中完成的。在NSOperation的start方法中,以此前建立的NSURLRequest對象為參數建立NSURLConnection並開啟連結。

在非同步回調的處理上二者也有區別,ASI採取的是CFHTTP請求完成,直接回調ASIHTTPRequest的執行個體方法,通過儲存的執行個體對象記錄的資訊完成Delegate模式或Block模式的回調。而AFN則直接使用了NSOperation的completionBlock屬性。

這些實現方式也可以看出,ASI顯得更加底層,並沒有過多使用Cocoa架構中已經封裝的API,而AFN則更加實用主義,邏輯簡單清晰,大量使用了架構API。這一點也是造成二者效能差別的原因之一。

總結

通過以上的對比,基本可以這樣評價:AFN適合邏輯簡單的應用,或者更適合開發資源尚不豐富的團隊,因為AFN的易用性要比ASI好很多,而這樣的應用(或團隊)對底層網路控制項的定製化要求也非常低。ASI更適合已經發展了一段時間的應用,或者開發資源相對豐富的團隊,因為往往這些團隊(或他們的應用)已經積累了一定的經驗,無論是產品上還是技術上的。需求複雜度就是在這種時候高起來,而且底層訂製的需求也越來越多,此時AFN就很難滿足需求,需要犧牲一定的易用性,使用ASI作為網路底層控制項。SegmentFault開源用戶端現在被設計為一款簡單的閱讀用戶端,幾乎沒有定製要求,因此,目前我選擇了AFN作為網路控制項。

以上對ASI和AFN兩款最常用的iOS底層網路控制項做了初步的介紹,要更深入的瞭解兩款控制項,還需要大家繼續研究各自的源碼。大家遇到任何關於iOS的技術

對比iOS網路組件:AFNetworking VS ASIHTTPRequest

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.