我有两个UITableViewControllers,我在它们之间使用故事板进行区分。
在prepareForSegue:sender:
中,第一个VC从Web服务获取NSArray,并使用下载的数据设置目标VC的模型。我将下载部分放入dispatch_queue_t
,因此它将异步运行而不会阻止UI线程。我想点击一个表格单元格,让UIActivityIndicatorView开始旋转,下载照片,下载照片时,停止微调器并继续使用segue。
在第一个UITableViewController中,我有一个prepareForSegue:sender:
方法:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"SelectPlace"]) {
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc]
initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[spinner startAnimating];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:spinner];
__block NSArray *photos = [[NSMutableArray alloc] init];
dispatch_queue_t downloadQueue = dispatch_queue_create("flickr download", NULL);
dispatch_async(downloadQueue, ^{
photos = [FlickrFetcher photosInPlace:[self.places objectAtIndex:indexPath.row] maxResults:50];
});
dispatch_release(downloadQueue);
[spinner stopAnimating];
[segue.destinationViewController setPhotos:photos withTitle:[[sender textLabel] text]];
}
}
现在它立即执行segue而不显示微调器或等待下载完成。
如何在不阻塞主线程的情况下异步下载数据以准备目标视图,还能不立即进行隔离?
答案 0 :(得分:9)
让目标视图控制器加载数据。当用户选择表中的行时,应立即转到新的视图控制器。这是保持用户界面活泼的必要条件。在prepareForSegue
中,为目标视图控制器提供加载自身所需的数据。然后在目标视图控制器的viewWillAppear
中,异步加载数据。
如果要保持目标视图控制器的通用性并避免从目标视图控制器执行闪烁照片提取,则可以设置具有getThePhotoData
方法且具有{{1}的方法的协议在dataSource
中设置为self
的目标视图控制器中的指针。然后,在目标视图控制器的prepareForSegue
中,异步调用viewWillAppear
。闪烁照片提取将在[dataSource getThePhotoData]
方法中进行,该方法将在触发segue的视图控制器中实现。
答案 1 :(得分:4)
在prepareForSegue中,你无法阻止segue。在拥有所有数据之前,您必须不要触发segue。因此,我建议您创建手动segue,并在下载所有数据时调用它。
例如,事件链可以与此类似: