7

我有两个 UITableViewControllers,我正在使用情节提要在它们之间进行切换。

prepareForSegue:sender:中,第一个 VC 从 Web 服务获取 NSArray,并使用下载的数据设置目标 VC 的模型。我将下载部分放入 a 中dispatch_queue_t,因此它将异步运行并且不会阻塞 UI 线程。我想点击一个表格单元格,让 UIActivityIndi​​catorView 开始旋转,下载照片,下载照片后,停止旋转器并继续转场。

在第一个 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,而不显示微调器或等待下载完成。

如何在不阻塞主线程的情况下异步下载数据以准备目标视图,也无需立即进行 segue?

4

2 回答 2

9

让您的目标视图控制器加载数据。当用户在您的表格中选择一行时,您应该立即转到新的视图控制器。这是保持用户界面快速的必要条件。在prepareForSegue中,为目标视图控制器提供它自己进行加载所需的数据。然后在viewWillAppear目标视图控制器中,异步加载数据。

如果您想保持目标视图控制器的通用性并避免从目标视图控制器中获取 Flicker 照片,您可以设置一个协议,该协议具有一个方法,例如,getThePhotoData并且在您的目标视图控制器中有一个dataSource指针,该指针设置为selfin prepareForSegue。然后,在viewWillAppear目标视图控制器中,[dataSource getThePhotoData]异步调用。闪烁照片获取将在getThePhotoData触发 segue 的视图控制器中实现的方法中进行。

于 2012-10-21T18:37:04.517 回答
5

在 prepareForSegue 中你不能停止 segue。在拥有所有数据之前,您最好不要触发 segue。因此,我建议您创建手动 segue 并在下载所有数据后调用它。

例如,事件链可能与此类似:

  1. 在您的 VC 注册通知 (dataReady:) 中的 viewDidLoad 并在 dealloc 中取消注册,
  2. 用户单击下载按钮并触发您的目标方法,您开始旋转动画
  3. 目标方法使用某个块(最好在某些模型中)下载所有数据,
  4. 在您发送通知的块末尾([[NSNotificationCenter defaultCenter] postNotificationName...),
  5. 您的 VC dataReady: 被调用并且您停止微调器并调用 [self performSegueWithIdentifier:...]
  6. Segue被触发
于 2012-10-21T18:27:48.850 回答