2012-05-10 166 views
5

我有UITableView有一些內容,這是加載在異步的方式。當用戶旋轉設備時,我需要在-willRotateToInterfaceOrientation方法中製作[tableView reloadData]。 ReloadData在我的情況下工作異步。如何讓MainThread等待一些異步操作完成?

我知道reloadData在主線程中工作,但它觸發cellForRowAtIndexPath,它在我的情況下工作異步。

所以問題是如何讓主線程等到UITableView's reloadData結束。

回答

2

如果您從willRotateToInterfaceOrientation調用reloadData,則會在主線程上調用它。事實上,UIViews不是線程安全的,只應該從主線程處理(在某些情況下,某人從另一個線程調用reloadData)。

我認爲有關「異步」作爲一個術語存在混淆。在主線程上調用UI委託的異步回調,如willRotateToInterfaceOrientation。異步並不一定意味着不同的線程(儘管「並行」異步運行)。

我會推薦閱讀關於NSRunLoop的Apple文檔。它是iOS應用程序運行方式的一個組成部分,是應用程序員必須理解的。

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html

+0

據我所知,主線程中調用reloadData。但realodData調用cellForRowAtIndexPath ...並且此方法需要加載一些數據異步。 –

+0

我看到了,所以你不是在等待reloadData完成,而是reloadData發起完成的異步任務。你能修改你的問題來反映這個嗎? NSRunLoop仍然是你想要的,雖然我不明白你爲什麼想要在異步數據加載時持有主線程人質。 – NSProgrammer

+0

需要主線程等待reloadData,因爲這會使旋轉動畫變得愉快。 –

3

您可以使用CFRunLoopRun 讓你的主線程等待,直到UITableView的數據重新加載。數據重新加載後,調用CFRunLoopStopCFRunLoopGetMain的結果作爲參數。

+0

謝謝,我看到這個不太容易閱讀文檔。我會試着去理解。 –

2

您需要在後臺加載表格的數據,然後調用UITableView的reloadData方法。

您可以使用GCD輕鬆地將加載函數異步分派到後臺隊列。當該任務完成時,讓工作線程返回主線程調用[tableView reloadData]的塊。這是如何:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{ 

    ... 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_async(queue, ^{ 

    // load your table data here 
    [self loadMyTableData]; 

    // when done dispatch back to the main queue to load the table 
    dispatch_queue_t mainQueue = dispatch_get_main_queue(); 
    dispatch_async(mainQueue, ^{ 

     [self.tableView reloadData]; 
     }); 
    }); 
    ... 
} 
+0

爲了使[self loadMyTableData];我需要更改一半的代碼來存儲數據,而不是將其推送到我的子類uitableviewcells,它的內容 –