2012-06-22 2 views
3

У меня есть объект, который при инициализации создает последовательный номер GCD, используя dispatch_queue_create, а также на вызовы освобождения dispatch_free. Во время жизни объекта в очередь добавляются блоки отправки, однако очередь также останавливается и запускается с использованием dispatch_suspend и dispatch_resume.Как я освобождаю и полностью освобождаю очередь Grand Central Dispatch при выпуске?

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

Как я понимаю, очередь не освобождается, пока не будет «нужна» в том смысле, что она больше не будет сохранена блоками отправки внутри нее. Это заставляет меня полагать, что для освобождения очереди я должен опорожнить ее, разрешив сначала блокировать внутри нее блокировки.

Что является самым простым и надежным способом решения этой проблемы?

ответ

7

Как правило, это не то, о чем вы должны слишком беспокоиться. От Memory Management for Dispatch Queues in the Concurrency Programming Guide:

Вы можете использовать dispatch_retain и dispatch_release функции увеличения и уменьшения, что счетчик ссылок по мере необходимости. Когда счетчик ссылок в очереди достигает нуля, система асинхронно освобождает очередь.

Поэтому, когда вы вызываете dispatch_release(myQueue), вы опускаете счетчик удержания, но любые задачи, все еще находящиеся в очереди, будут удерживать очередь. Это не пока они не закончат, что сохранить счетчик очереди будет равен 0. Таким образом, эта часть вашего вопроса:

Это приводит меня к мысли, что для освобождения очереди, я должен очистить его, позволяя блоки внутри его сначала выполнить до завершения.

Является точным. Если у вас есть задачи, которые вы, возможно, не захотите запускать в очереди, продолжайте читать.

Если вы приостанавливаете и возобновляете очередь из своего кода, это не вызывает проблемы - потому что вы ДОЛЖНЫ балансировать все приостановки и возобновление вызовов. Если вы оставите свою очередь в приостановленном состоянии, you're going to have a bad time. При этом у вас также есть возможность установить функцию очистки для очереди, используя dispatch_set_finalizer_f. Это не обязательно, но оно есть, если вам это нужно.

Теперь, основываясь на том, что вы здесь описываете, я бы предложил вместо этого использовать NSOperation и NSOperationQueue. Это слой более высокого уровня поверх GCD, который позволяет отменить задачи и сделать некоторые другие полезные вещи, которые намного сложнее сделать с помощью GCD напрямую.

+0

Спасибо за ответ! Дополнительные задачи не должны выполняться. Я смотрел дальше в «NSOperationQueue», и он выглядит хорошим кандидатом для решения моей проблемы. – Dan

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