Задача завершения NSURLSessionTask никогда не получает вызов в основной очереди с использованием GCD

Я использую iOS 7 NSURLSession, чтобы сделать простой GET для службы RESTful. Вот что я сделал:

NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration ephemeralSessionConfiguration];
_session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:nil delegateQueue:[NSOperationQueue mainQueue]]; 

// create your url at this line
NSURLRequest *request = [NSURLRequest requestWithURL:url];

NSURLSessionTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
   // do something with the result 
}]; 
[task resume];

Весь приведенный выше код работает нормально. завершенияHandler должен вызываться в основной очереди.

Однако, если я использую это в GCD, например:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
   // do some heavylifting in the background

   for (int i = 0; i < 10000000; i++) ;

   dispatch_async(dispatch_get_main_queue(), ^{
       // do the exact same thing as the above NSURLSession call
       NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration ephemeralSessionConfiguration];
       _session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:nil delegateQueue:[NSOperationQueue mainQueue]]; 

       // create your url at this line
       NSURLRequest *request = [NSURLRequest requestWithURL:url];

       NSURLSessionTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
          // do something with the result 
       }]; 
       [task resume];
   });
});

Теперь я подумал, что запускаю этот код в dispatch_get_main_queue(), который должен быть таким же, как [NSOperationQueue mainQueue], как указано в сеансе delegateQueue?? Tt должен эффективно работать в основном потоке, как и первый набор кода. Однако я обнаружил, что завершениеHandler никогда не вызывается. И если я уберу код GCD, он снова заработает.

Кто-нибудь пытался сделать это раньше? Должно ли это работать? или я неправильно понимаю, где работа была отправлена ​​в какую очередь?


person kawingkelvin    schedule 16.01.2014    source источник
comment
Можете ли вы завершить код в части GCD.   -  person KudoCC    schedule 16.01.2014
comment
я отредактировал часть GCD.   -  person kawingkelvin    schedule 16.01.2014
comment
что делает for (int i = 0; i < 10000000; i++) ;?   -  person Lithu T.V    schedule 16.01.2014
comment
это то, что занимает много времени, отправляя его в фоновый поток. Более реалистичным примером является чтение большого файла из /documents/, но вы поняли.   -  person kawingkelvin    schedule 16.01.2014
comment
Почему вы вызываете возобновление задачи вне асинхронного блока?   -  person Paul Dardeau    schedule 17.01.2014
comment
я дважды проверил скобки, задача возобновления вызывается в dispatch_get_main_queue(), позвольте мне отредактировать ее, чтобы лучше выровнять их   -  person kawingkelvin    schedule 18.01.2014
comment
Отредактировано, чтобы отразить, какой код относится к какому блоку. я тоже скучаю по ]; что я добавил. Вы можете быть уверены, что моя проблема не из-за этого упущения, а просто из-за ошибки в вырезании/вставке. Я убедился, что код работает без участия GCD.   -  person kawingkelvin    schedule 18.01.2014
comment
создание сеанса необходимо выполнить один раз, поэтому вне цикла.   -  person malhal    schedule 04.09.2016


Ответы (1)


Насколько мне известно, все обратные вызовы NSURLSession происходят в очереди, указанной свойством NSURLSession. delegateQueue только для чтения (docs), которые можно указать при инициализации.

person Clay Bridges    schedule 10.02.2014