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 имеет блок кода, который делает это, чтобы показать и скрыть индикатор сетевой активности.