Я новичок в очередях и потоках. Ниже приведен следующий код, который предназначен для запуска различных методов в асинхронной очереди. Каждый элемент в очереди будет обновлять счетчик, когда закончится, и когда все элементы будут выполнены в очереди, счетчик обновлений будет завершен и готов к возврату.dispatch_async не работает
Проблема в том, что когда этот код запускает последнюю строку, вызывается, а затем она зависает без ошибок, и я не могу продолжить прохождение трассировки.
__block int masterUpdateCount = 0;
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self updateStuffWithCompletionCount:^(int updatedItemsCount) {
masterUpdateCount += updatedItemsCount;
}];
[self updateMoreStuffWithCompletionCount:^(int updatedItemsCount) {
masterUpdateCount += updatedItemsCount; // Never gets called
}];
}); // <------ APPLICATION HANGS HERE after calling dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
return masterUpdateCount;
Что-то я заметил, что блоки завершающие никогда не дозвонились, что вполне может быть, почему она висит навсегда, но мой вопрос почему? Если это помогает, внутри методов типа updateStuffWithCompletionCount
я фактически инициализирую NSURLSession
с помощью NSURLSessionDataTask
, и я на самом деле выполняю задачу, вызвав [task resume];
, поэтому я не понимаю, почему завершение не будет вызвано.
Вот как он выглядит внутри метода updateStuffWithCompletionCount
:
- (void) updateStuffWithCompletionCount: (void (^)(int)) completionResult
{
__block int updateCount = 0;
NSString *someURL = @"www.someplace.com";
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: self delegateQueue: [NSOperationQueue mainQueue]];
NSURLSessionDataTask * getDataTask = [defaultSession dataTaskWithURL:[NSURL someURL] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
if(error == nil)
{
// do stuff, if updated, add to count
updateCount ++;
if(updateCount > 0) {
completionResult(updateCount); // Invoke the completion handler
} else {
completionResult(0); // Invoke the completion handler
}
}
else {
NSLog(@"Error: %@", error);
completionResult(-1);
}
}];
[getDataTask resume];
}
Надеюсь, опытный глаз может указать на это. Оценил.
Если вы звоните этот код на главном потоке, то вы будете блокировать основной поток из-за dispatch_group_wait – Paulw11
Попробуйте метод обновления внутри dispatch_async (dispatch_get_main_queue()) – brandonscript
Это будет та же проблема, потому что вы все еще на главной очереди. Вам нужно отправить его в другую очередь – Paulw11