Блок не завершен до перехода

Блок не завершен до нажатия следующего контроллера представления. Любые предложения о том, как отложить или реструктурировать следующее:

- (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 находок.


person user3131312    schedule 06.03.2014    source источник
comment
Перейдите в свою раскадровку (не используйте push-представление раскадровки) и замените функцию - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender. другой функцией, но делать то же самое. Тогда блок будет работать.   -  person lee    schedule 07.03.2014


Ответы (2)


Обратите внимание, что prepareForSegue служит только для подготовки. То есть, как только это будет сделано, переход будет выполнен. Поэтому, если вам нужно подготовить контроллер до того, как произойдет переход, вы не можете поместить эту задачу в асинхронный блок. Что касается цикла выполнения, ваш prepareForSegue завершается немедленно.

Если ваш следующий контроллер зависит от подготовительного кода в prepareForSegue, вам не следует делать dispatch_async. Вместо этого либо позвольте generateResults выполняться в основной очереди, либо позвольте ResultViewController отправить задачу асинхронно и обновить собственное представление на основе результата.

person krisk    schedule 07.03.2014
comment
следующий контроллер представления требует этого. Если я выполню его в основной очереди, блок завершится после инициализации следующего контроллера представления. Есть ли другой способ? - person user3131312; 07.03.2014

Решил, вот что сделал. Не было необходимости использовать диспетчеризацию. В качестве альтернативы блок завершается, когда 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) {
     }];
}

}

person user3131312    schedule 07.03.2014