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, но это привело к сбою. Я не знаю, конфликтует ли использование NSOperation в MKNetworkKit с этой проблемой. Спасибо за любую помощь!

- (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); в конце блока завершения он работает. Кто-нибудь знает, почему это происходит?


person James Kuang    schedule 08.08.2012    source источник


Ответы (1)


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

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

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

Другой способ — использовать KVO для ключевого пути «operationCount» в движке и проверить, достигает ли он нуля.

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

person Mugunth    schedule 13.08.2012