Чи підтримує ARC черги на відправлення?


95

Я читаю документацію Apple про "Управління пам'яттю для черг відправлення":

Навіть якщо ви реалізуєте зібране сміття додаток, ви все одно повинні зберігати та звільняти свої черги відправлення та інші об'єкти відправлення. Grand Central Dispatch не підтримує модель збору сміття для відновлення пам'яті.

Я знаю, що ARC не є збирачем сміття, але я хотів би бути впевненим, що мені не потрібно dispatch_retain і dispatch_release my dispatch_queue_t

Відповіді:


234

Коротка відповідь: ТАК, ARC зберігає та звільняє черги відправлення.







А тепер довга відповідь ...

Якщо ваша ціль розгортання нижча ніж iOS 6.0 або Mac OS X 10.8

Вам потрібно використовувати dispatch_retainі dispatch_releaseв черзі. ARC ними не керує.

Якщо вашою метою розгортання є iOS 6.0 або Mac OS X 10.8 або новішої версії

ARC буде керувати вашою чергою за вас. Вам не потрібно (і не можна) використовувати dispatch_retainабо dispatch_releaseякщо ARC увімкнено.

Деталі

Починаючи з iOS 6.0 SDK та Mac OS X 10.8 SDK, кожен об'єкт відправлення (включаючи a dispatch_queue_t) також є об'єктом Objective-C. Це задокументовано у <os/object.h>файлі заголовка:

 * By default, libSystem objects such as GCD and XPC objects are declared as
 * Objective-C types when building with an Objective-C compiler. This allows
 * them to participate in ARC, in RR management by the Blocks runtime and in
 * leaks checking by the static analyzer, and enables them to be added to Cocoa
 * collections.
 *
 * NOTE: this requires explicit cancellation of dispatch sources and xpc
 *       connections whose handler blocks capture the source/connection object,
 *       resp. ensuring that such captures do not form retain cycles (e.g. by
 *       declaring the source as __weak).
 *
 * To opt-out of this default behavior, add -DOS_OBJECT_USE_OBJC=0 to your
 * compiler flags.
 *
 * This mode requires a platform with the modern Objective-C runtime, the
 * Objective-C GC compiler option to be disabled, and at least a Mac OS X 10.8
 * or iOS 6.0 deployment target.

Це означає , що ви можете зберігати ваші черги в NSArrayабо NSDictionary, або в будинку з одним з strong, weak, unsafe_unretained, assign, або retainатрибутів. Це також означає, що якщо ви посилаєтесь на свою чергу з блоку, блок автоматично збереже чергу.

Отже, якщо вашою ціллю розгортання є принаймні iOS 6.0 або Mac OS X 10.8, і у вас увімкнено ARC , ARC збереже і звільнить вашу чергу, а компілятор позначить будь-яку спробу використання dispatch_retainабо dispatch_releaseяк помилку.

Якщо ваша мета розгортання принаймні IOS 6.0 або Mac OS X 10.8, і у вас є ARC відключена , необхідна вручну зберегти і звільнити свою чергу, або зателефонувавши по телефону dispatch_retainі dispatch_release, або шляхом відправки черзі retainі releaseповідомлення (як [queue retain]і [queue release]).

Для сумісності зі старою базою коди, ви можете запобігти компілятор бачити вашу чергу як об'єкт Objective-C, визначивши OS_OBJECT_USE_OBJCдля 0. Наприклад, ви можете помістити це у свій .pchфайл (перед будь-якими #importтвердженнями):

#define OS_OBJECT_USE_OBJC 0

або ви можете додати OS_OBJECT_USE_OBJC=0як макрос препроцесора у налаштуваннях збірки. Якщо ви встановите OS_OBJECT_USE_OBJCзначення 0, ARC не буде зберігати або звільняти вашу чергу для вас, і вам доведеться зробити це самостійно, використовуючи dispatch_retainта dispatch_release.


1
Однак зверніть увагу, що нова зміна позначає об'єкти відправлення як об'єкти Objective-C. Таким чином, навіть якщо ARC вимкнено, ці об'єкти автоматично зберігатимуться, якщо будуть захоплені блоком, як і всі інші об'єкти Objective-C.
Джоді Хейгінс,

3
Є цікавий крайній випадок. Якщо ваша бібліотека розгортається до iOS 5.1, а ваша програма до 6.0, і ви використовуєте ARC, вам потрібно dispatch_release і NULL об’єкт у deallocкоді 5.1 . В іншому випадку щось (код, згенерований компілятором? Сам час виконання?) Спробує звільнити об’єкт вдруге.
Стівен Фішер

Чи потрібно відправляти інші вихідні об'єкти, які я створюю під час використання Mac OS 10.7?
p0lAris

Ви повинні вручну зберегти / звільнити всі об'єкти GCD під OS X 10.7.
грабіж майофф

23

Просто продовжте тут ... Якщо ваша мінімальна ціль розгортання - iOS 6, ARC тепер керує ними.


Це стосується і гірського лева. Якщо вашою метою розгортання є iOS 6 або Mountain Lion, ви не можете (за замовчуванням) використовувати dispatch_release, оскільки це макрос, який надсилає повідомлення про випуск об’єкту, що не дозволено в ARC.
Еміль Ерікссон,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.