2015-11-14 2 views
0

Я новичок в очередях и потоках. Ниже приведен следующий код, который предназначен для запуска различных методов в асинхронной очереди. Каждый элемент в очереди будет обновлять счетчик, когда закончится, и когда все элементы будут выполнены в очереди, счетчик обновлений будет завершен и готов к возврату.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]; 
} 

Надеюсь, опытный глаз может указать на это. Оценил.

+0

Если вы звоните этот код на главном потоке, то вы будете блокировать основной поток из-за dispatch_group_wait – Paulw11

+0

Попробуйте метод обновления внутри dispatch_async (dispatch_get_main_queue()) – brandonscript

+1

Это будет та же проблема, потому что вы все еще на главной очереди. Вам нужно отправить его в другую очередь – Paulw11

ответ

0

Включите код для своих данных. Задайте пожалуйста. Эта строка masterUpdateCount += updatedItemsCount; // Never gets called, потому что ее в блоке завершения, что означает, что она не запускается до тех пор, пока ваша датазагрузка не будет завершена, задали ли вы точку останова в своей области данных и убедитесь, что что-то там прыгает туда? У вас есть строка NSLog (% @, error.description) там, где вы ее получаете? Похоже, вам, возможно, потребуется сделать больше отладки.

+0

В настоящее время он включен :). Я установил точки останова в 'getDataTask', и, похоже, он вообще не прыгает. Ошибка также не печатается. Это как будто его игнорируют полностью, несмотря на вызов '[getDataTask resume]' – Marcel

Смежные вопросы