在segue之前没有完成阻止

时间:2014-03-06 17:24:25

标签: objective-c objective-c-blocks grand-central-dispatch segue

在推送下一个视图控制器之前,块未完成。有关如何延迟或重组以下内容的任何建议:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:@"ResultsView"])
{
    [self.spinner startAnimating];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSMutableArray *results = [[NSMutableArray alloc] init];
        results = [self generateResults];

        dispatch_async(dispatch_get_main_queue(), ^{

            [self.spinner stopAnimating];

            ResultViewController *controller = [segue destinationViewController];
            controller.results = results;

        });
    });
}
}

这是generateResults方法:

- (NSMutableArray *)generateResults
{
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
__block NSMutableArray *matches = [[NSMutableArray alloc] init];

[library enumerateGroupsWithTypes:ALAssetsGroupAll
                       usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
    if (group) {
        [group setAssetsFilter:[ALAssetsFilter allPhotos]];
        [group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop){

            if (asset)
            {
                //work done here.
            }
        }];
    }
} failureBlock:^(NSError *error) {
}];

return matches;
}

或者,当我不使用调度同步时,那么相同的问题,生成结果的块就太晚完成了。已出现下一个视图控制器,显示0个查找。

2 个答案:

答案 0 :(得分:1)

请注意,prepareForSegue仅用作准备。也就是说,一旦完成,segue将执行。因此,如果需要在segue发生之前准备控制器,则不能将此任务放在异步块中。 就runloop而言,您的prepareForSegue会立即完成

如果您的下一个控制器依赖于prepareForSegue中的预备代码,那么您不应该执行dispatch_async。相反,要么让generateResults在主队列上执行,要么让ResultViewController将任务调度为异步,并根据结果更新自己的视图。

答案 1 :(得分:0)

解决了,这就是我所做的。没有必要使用派遣。或者,在group == nil时块完成。所以一个简单的else语句就可以了。

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"ResultView"])
{
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    __block NSMutableArray *matches = [[NSMutableArray alloc] init];

    [library enumerateGroupsWithTypes:ALAssetsGroupAll
                           usingBlock:^(ALAssetsGroup *group, BOOL *stop)
     {
         if (group) {
             [group setAssetsFilter:[ALAssetsFilter allPhotos]];
             [group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop){

                 if (asset)
                 {

                 }
             }];
         } else {

             ResultsViewController *resultsViewController = [segue destinationViewController];
             resultsViewController.results = matches;
             [resultsViewController.collectionView reloadData];
         }
     } failureBlock:^(NSError *error) {
     }];
}

}