Как правильно освободить свойство очереди отправки GCD? - PullRequest
19 голосов
/ 01 апреля 2011

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

@property (nonatomic, assign) dispatch_queue_t queue;

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

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

Как мне правильно освободить это?Будет ли работать retain/release сработать?

Что произойдет, если в очереди ожидают / работают какие-либо вещи во время вызова release?

Ответы [ 4 ]

20 голосов
/ 01 апреля 2011

Следующее украдено из документации разработчика:

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

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

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

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

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

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

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

8 голосов
/ 17 января 2012

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

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

https://github.com/joshrl/GDCQueueDeallocTest

2 голосов
/ 13 сентября 2012

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

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

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

1 голос
/ 01 апреля 2011

Что произойдет, если в очереди ожидают / работают какие-либо вещи во время вызова release?

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

...