如何在继续使用segue之前等待另一个线程完成?

jje*_*ton 7 asynchronous ios ios5 uistoryboardsegue

我有两个UITableViewControllers,我在它们之间使用故事板进行区分.

prepareForSegue:sender:,第一个VC从Web服务获取NSArray,并使用下载的数据设置目标VC的模型.我把下载部分放入一个dispatch_queue_t所以它将异步运行而不是阻止UI线程.我想点击一个表格单元格,让UIActivityIndi​​catorView开始旋转,下载照片,下载照片时,停止微调器并继续使用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]];
    }

}
Run Code Online (Sandbox Code Playgroud)

现在它立即执行segue而不显示微调器或等待下载完成.

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

vac*_*ama 9

让目标视图控制器加载数据.当用户选择表中的行时,应立即转到新的视图控制器.这是保持用户界面活泼的必要条件.在prepareForSegue,为目标视图控制器提供加载自身所需的数据.然后在viewWillAppear目标视图控制器中,异步加载数据.

如果你想保持目标视图控制器通用的,避免做的闪烁光从目标视图控制器读取,你可以设置有这样的制作方法的协议getThePhotoData,并有dataSource在设置为目的地视图控制器指针selfprepareForSegue.然后,在viewWillAppear目标视图控制器中,[dataSource getThePhotoData]异步调用.闪烁照片提取将在getThePhotoData方法中进行,该方法将在触发segue的视图控制器中实现.

  • 我更新了答案,为您提供了更多选择.你真的不想在`prepareForSegue`中加载数据,因为用户期望UI立即转换,而不是在5秒之后从网络加载数据. (2认同)

Tom*_*cki 5

在prepareForSegue 中,您无法停止segue。在您拥有所有数据之前,您一定不要触发 segue。因此,我建议您创建手动转场并在下载所有数据后调用它。

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

  1. 在您的 VC 在 vi​​ewDidLoad 中注册通知 (dataReady:) 并在 dealloc 中取消注册,
  2. 用户点击下载按钮并触发你的目标方法,你开始微调动画
  3. 目标方法使用某个块(最好在某些模型中)下载所有数据,
  4. 在块的末尾发送通知([[NSNotificationCenter defaultCenter] postNotificationName...),
  5. 你的 VC dataReady: 被调用,你停止微调器并调用 [self performSegueWithIdentifier:...]
  6. Segue 被触发