2012-04-11 76 views
12

這裏的情景:開放異步Web請求處理時的UIViewController被彈出(AFNetworking)

-A的UIViewController(A)推到使用AFNetworking導航堆棧
-On viewDidLoad中的異步GET被稱爲(一singleton AFHTTPClient在應用程序中共享)來填充視圖上的各種用戶元素(比如UILabel)。
- 用戶按下後退按鈕請求返回
-assume其他活動視圖控制器可以發出請求,所以你不能取消所有打開的操作

所以問題#1,你應該跟蹤打開請求之前由UIViewController A創建,並在用戶離開視圖時取消未完成的視圖,或者讓他們完成並忽略它們?由於AFNetworking使用塊,正在更新的用戶元素將保留在塊內部,因此在彈出視圖後執行成功/失敗塊時不會導致崩潰。然而忽略它們的缺點似乎是不必要的網絡流量。

問題#2是,你會在哪裏執行代碼來取消UIViewController A所做的操作? viewDidDisappear看起來不正確,因爲用戶可能前進(將新視圖推入堆棧)而不是後退(彈出當前視圖),在這種情況下,您不想取消打開的請求,因爲用戶可能會回到當前視圖,並且不會再次加載。但是,我並不認爲dealloc或viewDidUnload將在請求執行時被調用,因爲該塊將保留用戶元素上的保留,所以我不認爲它可以去那裏。

對此會很感激。你認爲最佳做法是什麼?

+1

附註:viewDidUnload與其視圖控制器的保留計數無關。它在視圖控制器想要擺脫其視圖時調用(並可能稍後重新加載它)。例如,當您收到內存警告時,會出現在選項卡或導航控制器中的任何離屏視圖控制器。所以它可以在你的請求正在進行時被調用。 – rickster 2012-04-12 03:47:31

回答

7

一般而言,當用戶離開視圖控制器時,並不需要取消請求。在內存管理方面,引用block self可以防止發送消息給釋放實例造成的崩潰,所以不用擔心。就用戶體驗而言,我認爲在問題出現之前您不應該擔心它(我們的開發人員有一個訣竅,猜測在我們的應用程序中速度會變慢)。但是,如果你正在進行大量的GET請求,並且它造成了明顯的緩慢,我的建議是讓控制器在-viewDidUnload:中執行HTTPClient -cancelAllHTTPOperationsWithMethod:path:(任何其他回調會過早)。

+1

爲什麼要在'viewDidUnload:'中取消請求?我認爲應該在彈出視圖控制器後立即取消請求。更好的方法是檢查視圖控制器是否仍在'viewDidDisappear:'的堆棧中。如果不是,請取消該請求。你可以使用'if(![self.navigationController.viewControllers containsObject:self]){NSLog(@「Cancel request」)來檢查它。 }' – nonamelive 2012-05-08 14:43:22

+0

你在想這件事。在某些情況下,取消立即變得更有意義,但由於用戶在彈出視圖後立即推送並不罕見,因此可能無法過分主動。 – mattt 2012-05-08 17:30:16

0

也許你可以擁有一個管理所有網絡資源的單例,並且只需將它的代理設置爲當前的vc(在viewDidLoad中),以便獲取任何傳入數據,並在vc消失時發送取消消息讓一個不同的vc成爲它的代表)。或者單身人士可以在稍後階段保存任何vc的訪問數據。出於這個原因,我傾向於將異步代碼放入我的VC中。

+0

我知道如何跟蹤哪些請求取消,問題是你應該取消它們,如果是的話,應該取消它們(因爲viewDidUnload和dealloc在請求完成之前不會被調用)。 – Joel 2012-04-11 21:20:48

+0

@Joel你可以檢查視圖控制器是否在'viewDidDisappear:'中彈出。請參閱我在mattt的答案中留下的評論。 – nonamelive 2012-05-08 15:16:00

+1

謝謝。我也在這個問題後瞭解到,你可以通過這樣做來檢查viewDidDisapper中的pop:if([self isMovingFromParentViewController] || [self isBeingDismissed]) – Joel 2012-05-08 15:27:29