MKNetworkKit и GCD dispatch_group_t

Я пытаюсь использовать MKNetworkKit для извлечения массива ссылок из веб-службы, затем анализировать каждый ответ в фоновом потоке и использовать dispatch_group_t GCD, чтобы дождаться завершения обработки всех потоков. Я застрял в том, что не могу понять, почему мой dispatch_group_notify не ожидает завершения всех потоков в группе. Запуск этого кода выведет:

results count: 0
added into results, count: 1
added into results, count: 2

Группа рассылки не ожидает своих потоков. Я также попытался dispatch_group_wait, но это дало мне сбой. Я не знаю, противоречит ли MKNetworkKit использование NSOperation с этой проблемой. Спасибо за любую помощь!

- (MKNetworkOperation *)getABunchOfMovies:(NSArray *)movies onCompletion:(CastResponseBlock)completionBlock onError:(MKNKErrorBlock)errorBlock
{
    MKNetworkOperation *operation;
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    block NSMutableArray *results = [[NSMutableArray alloc] initWithCapacity:[movies count]];

    for (NSString *movieTitle in movies) {
        operation = [self operationWithPath:REQUEST_URL(API_KEY, [movieTitle urlEncodedString])];

        [operation onCompletion:^(MKNetworkOperation *completedOperation) {

            dispatch_group_async(group, queue, ^{
                NSDictionary *response = [completedOperation responseJSON];
                id result = [self processResponse:response withMovieTitle:movieTitle];

                @synchronized (results) {
                    [results addObject:result];
                    NSLog(@"added into results, count: %d", [results count]);
                }
            });
        }
                        onError:^(NSError *error) {
                            errorBlock(error);
                        }];

        [self enqueueOperation:operation];
    }

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{

        NSLog(@"results count: %d", [results count]);

        // Return array here
        completionBlock(results);
    });

    dispatch_release(group);

    return operation;
}

Изменить: я до сих пор не могу понять, почему, но если я изменю его на использование dispatch_group_enter(group); и сопоставьте его с dispatch_group_leave(group); в конце блока завершения, это работает. У кого-нибудь есть идеи, почему это происходит?

1 ответ

Решение

На данный момент MKNetworkKit не поддерживает обработчики завершения очереди. Вы должны рассмотреть возможность добавления зависимости от операций вместо этого хака.

[lastOperation addDependency:op1];
[lastOperation addDependency:op2];

и предположим, что когда "lastOperation" завершается, очередь действительно завершена.

Другой способ состоит в том, чтобы KVO указывал путь к файлу "operationCount" на двигателе и проверял, не достигает ли он нуля.

MKNetworkEngine имеет блок кода, который делает это, чтобы показать и скрыть индикатор сетевой активности.

Другие вопросы по тегам