我有一些以异步方式UITableView
加载的内容。当用户旋转设备时,我需要制作方法。在我的情况下,ReloadData 异步工作。[tableView reloadData]
-willRotateToInterfaceOrientation
我知道 reloadData 在主线程中工作,但它会触发 cellForRowAtIndexPath,在我的情况下它是异步的。
所以问题是如何让主线程等到UITableView's reloadData
结束。
我有一些以异步方式UITableView
加载的内容。当用户旋转设备时,我需要制作方法。在我的情况下,ReloadData 异步工作。[tableView reloadData]
-willRotateToInterfaceOrientation
我知道 reloadData 在主线程中工作,但它会触发 cellForRowAtIndexPath,在我的情况下它是异步的。
所以问题是如何让主线程等到UITableView's reloadData
结束。
您可以使用CFRunLoopRun 让您的主线程等待 UITableView 数据重新加载。数据重新加载后调用CFRunLoopStop传递 CFRunLoopGetMain 的结果作为参数。
如果您从 willRotateToInterfaceOrientation 调用 reloadData,那么它会在主线程上调用。事实上,UIViews 不是线程安全的,只能从主线程处理(以防有人出于某种原因想到从另一个线程调用 reloadData)。
我认为与“异步”一词有关的混淆。像 willRotateToInterfaceOrientation 这样的 UI 委托的异步回调在主线程上调用。异步并不一定意味着不同的线程(尽管“并行”异步运行确实如此)。
我建议阅读有关 NSRunLoop 的 Apple 文档。它是 iOS 应用程序运行方式不可或缺的一部分,是应用程序程序员必须了解的。
您需要在后台加载表格数据,然后调用 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];
});
});
...
}