5

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

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

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

4

3 回答 3

3

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

于 2012-05-10T13:57:59.233 回答
2

如果您从 willRotateToInterfaceOrientation 调用 reloadData,那么它会在主线程上调用。事实上,UIViews 不是线程安全的,只能从主线程处理(以防有人出于某种原因想到从另一个线程调用 reloadData)。

我认为与“异步”一词有关的混淆。像 willRotateToInterfaceOrientation 这样的 UI 委托的异步回调在主线程上调用。异步并不一定意味着不同的线程(尽管“并行”异步运行确实如此)。

我建议阅读有关 NSRunLoop 的 Apple 文档。它是 iOS 应用程序运行方式不可或缺的一部分,是应用程序程序员必须了解的。

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

于 2012-05-10T13:53:40.377 回答
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];
      });
  });
  ...
}
于 2012-05-10T14:26:39.593 回答