Подтвердить что ты не робот

Каков правильный способ освободить свойство очереди отправки GCD?

Я использую dispatch_queue, доступ к которому осуществляется через свойство его владельца, например:

@property (nonatomic, assign) dispatch_queue_t queue;

Обратите внимание на ключевое слово assign. Очередь используется во всех объектах жизни и, следовательно, принадлежит объекту. Я освобождаю очередь, когда объект-владелец освобождается:

-(void)dealloc
{
    dispatch_release(self.queue);
    self.queue = nil;
}

Как правильно отпустить это? Используется ли retain/release?

Что произойдет, если во время вызова релиза есть вещи, ожидающие/запущенные в очереди?

4b9b3361

Ответ 1

В документации разработчика содержится следующее:

Очереди отправки и другая отправка объекты - данные с подсчетом ссылок типы. Когда вы создаете серию очереди отправки, он имеет начальную счетчик ссылок 1. Вы можете использовать отправка и отправка_отправка функции для увеличения и уменьшения эта ссылка подсчитывается по мере необходимости. когда подсчет ссылок в очереди ноль, система асинхронно освобождает очередь.

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

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

Таким образом, везде, где бы вы ни воспользовались, воспользуйтесь диспетчерской отправкой и в любом месте, которое вы использовали бы - освободите использование dispatch_release.

Очереди отправки следуют тем же общим соглашениям об управлении памятью, что и объекты objective-c. И они не будут отменены до тех пор, пока все блоки в очереди не закончатся.

Если вам нужен способ закрыть очередь отправки: нет способа отменить все блокированные блоки с помощью любого API, поэтому они всегда должны выполняться до завершения. Одним из способов ускорения этого процесса является наличие переменной BOOL в классе, управляющем очередью отправки: _isValid. Когда вы хотите закрыть очередь, вы можете установить _isValid в NO. Все блоки, отправленные в очередь, должны сначала проверить _isValid перед выполнением любой работы.

Комментарий стороны: может быть более целесообразным использовать NSOperationQueue. См. Chris Hanson сообщение в блоге.

Ответ 2

Интересно, что если блоки, переданные в очередь, ссылаются на объект, которому принадлежит очередь (например, "self" ), объект не будет попадать в dealloc, пока все ожидающие блоки в очереди не будут завершены.

Вот проект, который демонстрирует это:

https://github.com/joshrl/GDCQueueDeallocTest

Ответ 3

настройте свое свойство следующим образом:

@property (readwrite, strong, nonatomic) __attribute__((NSObject)) dispatch_queue_t queue;

Назначение подразумевается, а Strong будет сохранять очередь, сообщающую ARC, рассматривать ее как NSObject.

Ответ 4

Что происходит, если есть вещи ожидание/запуск в очереди вызывать выпуск?

Это безопасно. ожидающая/работающая очередь сохраняется из системы. Вызов dispatch_release влияет только на количество оставшихся в очереди. См. Man-страницу dispatch_async или так далее.