2017-02-06 65 views
0

我在我的ViewController中有一個UITableView。要填充它,我必須提出一個async請求,可能需要一秒鐘才能完成。我應該把它放在哪裏?哪裏是填充UITableView的正確位置?

當我試圖讓ViewDidLoad異步,並從那裏打電話,ViewWillLayoutSubviews拋出一個錯誤,因爲它試圖不分配,一些元素的位置,但 - 由於不是從ViewDidLoad所有代碼在尚未執行的事實(我認爲)。

+0

你獲取的數據後,你會怎麼辦?例如,更新UI。 – Lumialxk

+0

是的,我會做'_tableView.Source = ...; _tableView.ReloadData();' – nicks

回答

2

在等待ViewDidLoad中的任何內容之前,您需要設置所有視圖邏輯。否則當ViewDidLoad方法返回時,您的視圖初始化將不會完成。這可能是導致ViewWillLayoutSubviews失敗的一個潛在原因。如果仍然失敗,則使用一個try/catch,以確保您的服務工作:

public override async void ViewDidLoad() 
{ 
    base.ViewDidLoad(); 

    // setup all the view elements here (before the async call) 

    try 
    { 
     var results = await MakeYourAsyncRequest(); 

     InvokeOnMainThread(() => 
     { 
      _tableView.Source = ...; // do something with the results 
      _tableView.ReloadData(); 
     }); 
    } 
    catch(Exception ex) 
    { 
     // do something with the exception 
    } 
} 
+0

好的。但爲什麼'Task.Run'和'InvokeOnMainThread'而不是'ViewDidLoad'' async'並且從那裏發出'await'請求? – nicks

+0

基本上,因爲ViewDidLoad是iOS定義和調用的方法,不是異步的。在C#中使它異步並不意味着iOS將等待它。這就是爲什麼'ViewWillLayoutSubviews'可能會失敗 – xleon

+0

你能否提供這些信息的來源? – nicks

0

試着把tableView.ReloadData();方法裏面

dispatch_async(dispatch_get_main_queue()^ {}這可能會幫助您解決問題

- :一般來說,你應該儘量確保所有的用戶界面交互的發生主線程。您的信息獲取任務將在後臺運行。它看起來像你從你的 後臺線程,這似乎是有風險的調用重載數據。

0

根據數據對我會把在通話AppDelegate。當應用程序啓動時,應該獲取並保存數據。

當您的UITableview出現時,它將已經準備好數據或者可能是錯誤消息,因爲您已經知道提取結果。

該數據可能會改變這就是爲什麼我還會將您的ViewControllerviewWillAppear()中的獲取呼叫與UITableview放在一起。

ViewDidLoad()是一種只被調用一次的方法。它也被稱爲ViewController生命週期的第一個方法。 如果你讀了一下VC lifecycle,那就太好了。 您可以通過在代碼中嘗試它來幫助自己printf("method name").

+0

我認爲在AppDelegate上獲取數據是非常棘手的,除非您需要它進行應用程序初始化。想象一下,你有20個視圖控制器,每個視圖控制器發出異步請求。你會在AppDelegate中提出所有這些請求嗎? – xleon

+0

我同意你@xleon。我不知道他的用例場景。只有當我需要它像你提到的應用程序初始化時,或者如果數據很重要,但當用戶不使用該應用程序時可能會改變,我會這樣做。 – Darkwonder

相關問題