iOS 網路請求在 Controller 退出後是否應該被取消?

MrPeak發表於2016-10-18

一個編寫iOS程式碼的經典場景:使用者進入某個Controller,發起Http網路請求從Server獲取資料,在資料返回之前使用者退出了Controller。此時是否需要Cancel之前發出的網路請求呢?

如果請求的資料只在當前Controller產生內容,結論當然是需要Cancel,雖然我知道不少iOS程式設計師因為偷懶而忘了取消。我們用工程的思維,深入本質,一起看下這背後都發生了什麼,如果不Cancel會有哪些副作用。

我們可以把一個Http請求分為這幾步:

第一步:三次握手

這一步會有三個packet產生,sync,sync+ack,ack。

第二步:客戶端傳送Http的request

此處根據請求型別產生的packet數量會有差異。

第三步:客戶端接收Server的Http Response

根據Response的大小,產生的packet數量不相同,一般一個packet在1.5KB左右。

通過程式碼檢視測試樣本

我們在Demo專案中執行如下程式碼,再配合tcpdump抓包看看背後究竟發生了什麼?

下圖是tcpdump獲取的結果:

netcancel00

  • 圖中標號1,2,3表示的tcp三次握手。
  • 標號4是客戶端傳送Http Get,標號5是Server Ack。
  • 標號6是Server Response。

後面還有幾個斷開tcp連線的包被我省去了,前面這6個packet足以說明問題了。

上述三步中,前兩步消耗的是使用者上行的流量,第三步用的下行的流量。國內移動運營商對於上行和下行的流量都算在包月的總流量當中的,所以如果使用者在第六個或者之後的Packet沒有返回之前退出Controller的話,後續的Packet依然會通過連線,走下行通道,抵達我們的客戶端,耗費使用者的流量,Response往往還是一個請求的流量大頭。

如果我們在請求返回之前,呼叫Cancel:

取消請求的話,客戶端會傳送如下一個Reset Packet斷開當前的Http連線,阻止後續的流量產生:

netcancel01

所以結論是:如果不Cancel,請求完成之後通過回撥找到delegate,如果是weak引用,Controller被釋放,delegate變為nil,業務流程被中斷,程式碼還算安全。但是會的的確確浪費一些使用者流量。養成好習慣,自己產生的垃圾自己清理哦。

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

iOS 網路請求在 Controller 退出後是否應該被取消?

相關文章