dispatch_async пользовательская очередь никогда не выходит из блока - PullRequest
5 голосов
/ 30 ноября 2011
dispatch_queue_t callerQueue = dispatch_get_current_queue();
dispatch_retain(callerQueue);
dispatch_queue_t downloadQueue = dispatch_queue_create("Download Queue",NULL);

dispatch_async(downloadQueue, 
^{
    //some code that accesses a web service
    dispatch_async(callerQueue,
    ^{
      //some code that accesses UI
    });
});
dispatch_release(downloadQueue);
NSLog(@"great successing!");

Проблема в том, что "Великий успех!" никогда не появляется, и ничего не происходит за пределами конца кода dispatch_async. Я не уверен, что делаю не так, но знаю, что с этим что-то серьезно не так.

Ответы [ 2 ]

4 голосов
/ 30 ноября 2011

Вы слишком рано освобождаете очередь загрузки. Вам нужно подождать, пока он не выполнит блок. dispatch_async man-страница предлагает поместить выпуск в конец блока.

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

2 голосов
/ 02 декабря 2011

Есть несколько проблем с этим кодом:

  1. Вам не нужно сохранять CallerQueue после его создания. Он уже создан с сохранением количества 1 и, вероятно, исчезнет, ​​как только вы отпустите его позже. Сохраняя его дважды, вы потенциально создаете утечку.

  2. Вы никогда не должны выполнять операции пользовательского интерфейса в какой-либо другой очереди, кроме основной (в данном случае это не callerQueue).

Остальная часть кода выглядит нормально (и вам не нужно освобождать очередь загрузки изнутри блока, как предлагают другие, поскольку вызов dispatch_async () также сохранит его. В этом коде должно быть больше фрагмент, который мы пропустили (например, выходит ли код сразу после выполнения NSLog ()?).

...