如何使MainThread等到某些异步操作完成?

时间:2012-05-10 13:44:08

标签: objective-c ios multithreading uitableview asynchronous

我有UITableView一些内容,以异步方式加载。当用户旋转设备时,我需要在[tableView reloadData]方法中进行-willRotateToInterfaceOrientation。在我的情况下,ReloadData异步工作。

我知道reloadData在主线程中工作,但它会触发cellForRowAtIndexPath,在我的情况下它会异步。

所以问题是如何使主线程等到UITableView's reloadData结束。

3 个答案:

答案 0 :(得分:3)

您可以使用CFRunLoopRun 使主线程等待,直到重新加载UITableView数据。重新加载数据后,调用CFRunLoopStop作为参数传递CFRunLoopGetMain的结果。

答案 1 :(得分:2)

如果从willRotateToInterfaceOrientation调用reloadData,则在主线程上调用它。实际上UIViews不是线程安全的,只能从主线程处理(如果由于某种原因有人想到从另一个线程调用reloadData)。

我认为有关“异步”作为术语的混淆。在主线程上调用诸如willRotateToInterfaceOrientation之类的UI委托的异步回调。异步并不一定意味着不同的线程(虽然“并行”异步运行)。

我建议您阅读NSRunLoop的Apple文档。它是iOS应用程序运行方式中不可或缺的一部分,是应用程序员理解的必备条件。

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

答案 2 :(得分: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];
      });
  });
  ...
}