Как я могу упорядочить асинхронные фоновые задачи с помощью GCD?

Я использую GCD на iOS для выполнения трудоемкой задачи в фоновом потоке. В API есть метод запуска, который принимает в качестве аргументов два блока, оба вызываются в основной очереди. Первый вызывается при запуске задачи, а второй — при завершении задачи. Это все работает.

На самом деле мне нужно выполнить несколько таких трудоемких задач. API позволяет мне запускать их все одновременно, а затем ждать завершения каждого из них и обновлять пользовательский интерфейс через блоки. Они работают одновременно.

Однако на самом деле я хочу упорядочить трудоемкие задачи (по-прежнему запуская каждую с использованием описанного API), чтобы я мог запускать их все одновременно, запускать первую и давать мне ее обратные вызовы, затем запустите второй и дайте мне его обратные вызовы и т. д., пока все не будет сделано.

Каков наилучший способ добиться этого с помощью GCD и блоков?

Если бы задачи были синхронными, у меня был бы просто цикл, который запускал бы каждую по очереди, и запускал бы все это асинхронно. Но у меня есть обратные вызовы, так что это не сработает. Я бы предпочел не связывать их в цепочку, поскольку объект, из-за которого все это происходит, может исчезнуть, как только он запустит последовательность событий.


person Steve Weller    schedule 26.08.2011    source источник
comment
Чтобы уточнить: добавление последовательной очереди с другой стороны API решает эту проблему. Ключевой вопрос заключается в том, как добиться того же самого с текущим API и его асинхронным параллельным поведением?   -  person Steve Weller    schedule 26.08.2011


Ответы (2)


Вы можете создать свою собственную последовательную очередь, которая будет выполняться в порядке FIFO с помощью dispatch_queue_create. Вам НЕ нужно указывать, что это последовательная очередь. Он будет действовать таким образом по умолчанию.

Образец создания очереди:

dispatch_queue_t my_q = dispatch_queue_create("Serial",NULL);

Эта очередь принадлежит вам, поэтому, если вы не освободите ее (с помощью dispatch_release), произойдет ее утечка.

Дополнительная информация находится в Документация Apple здесь.

person Ben Mosher    schedule 26.08.2011
comment
Практическое решение таково, как вы описываете: под API создайте пользовательскую очередь, ориентированную на параллельную очередь (это работает, я пробовал). Однако это не тот вопрос, который задают. Вопрос требует только использования доступного асинхронного API. - person Steve Weller; 26.08.2011

Есть ли особая причина, по которой вы должны использовать GCD? Похоже, NSOperationQueue с параллелизмом 1 — это именно то, что вам нужно.

person jsd    schedule 26.08.2011
comment
NSOperationQueue является высокоуровневым, но неуклюжим, и самым большим препятствием является отсутствие захвата значений переменных. GCD также позволяет мне перепроектировать мои API, например, избавиться от отношений делегирования. - person Steve Weller; 26.08.2011