繁体   English   中英

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

[英]How to make MainThread wait till some async action is done?

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

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

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

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

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

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

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

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

您需要在后台加载表的数据,然后调用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];
      });
  });
  ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM