¿ARC admite colas de despacho?

95

Estoy leyendo la documentación de Apple sobre "Gestión de memoria para colas de despacho":

Incluso si implementa una aplicación de recolección de basura, aún debe retener y liberar sus colas de envío y otros objetos de envío. Grand Central Dispatch no admite el modelo de recolección de basura para reclamar memoria.

Sé que ARC no es un recolector de basura, pero me gustaría estar seguro de que no necesito dispatch_retain y dispatch_release mi dispatch_queue_t

flagg19
fuente

Respuestas:

234

La respuesta corta: SÍ, ARC retiene y libera las colas de despacho.







Y ahora para la respuesta larga ...

Si su destino de implementación es inferior a iOS 6.0 o Mac OS X 10.8

Necesita usar dispatch_retainy dispatch_releaseen su cola. ARC no los gestiona.

Si su destino de implementación es iOS 6.0 o Mac OS X 10.8 o posterior

ARC administrará su cola por usted. No necesita (y no puede) usar dispatch_retaino dispatch_releasesi ARC está habilitado.

Detalles

A partir del SDK de iOS 6.0 y del SDK de Mac OS X 10.8, cada objeto de envío (incluido a dispatch_queue_t) también es un objeto de Objective-C. Esto está documentado en el <os/object.h>archivo de encabezado:

 * 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.

Esto significa que puede almacenar su cola en una NSArrayo NSDictionary, o en una propiedad con una de las strong, weak, unsafe_unretained, assign, o retainatributos. También significa que si se refiere a su cola desde un bloque, el bloque retendrá la cola automáticamente.

Entonces, si su objetivo de implementación es al menos iOS 6.0 o Mac OS X 10.8, y tiene ARC habilitado , ARC retendrá y liberará su cola, y el compilador marcará cualquier intento de uso dispatch_retaino dispatch_releasecomo un error.

Si su objetivo de implementación es al menos iOS 6.0 o Mac OS X 10.8, y tiene ARC deshabilitado , debe retener y liberar manualmente su cola, ya sea llamando dispatch_retainy dispatch_release, o enviando la cola retainy los releasemensajes (como [queue retain]y [queue release]).

Para lograr compatibilidad con bases de código antiguas, puede evitar que el compilador vea su cola como un objeto Objective-C definiendo OS_OBJECT_USE_OBJCa 0. Por ejemplo, puede poner esto en su .pcharchivo (antes de cualquier #importdeclaración):

#define OS_OBJECT_USE_OBJC 0

o puede agregar OS_OBJECT_USE_OBJC=0como una macro de preprocesador en su configuración de compilación. Si se establece OS_OBJECT_USE_OBJCque 0, ARC no retener o liberar la cola para usted, y usted tendrá que hacerlo usted mismo usando dispatch_retainy dispatch_release.

Rob Mayoff
fuente
1
Sin embargo, tenga en cuenta que el nuevo cambio designa los objetos de envío como objetos Objective-C. Por lo tanto, incluso si ARC está deshabilitado, estos objetos se retendrán automáticamente si son capturados por un bloque, al igual que todos los demás objetos de Objective-C.
Jody Hagins
3
Hay un caso extremo interesante. Si su biblioteca se implementa en iOS 5.1 y su aplicación en 6.0 y está usando ARC, necesita dispatch_release y NULL el objeto en su dealloccódigo 5.1 . De lo contrario, algo (¿código generado por el compilador? ¿El tiempo de ejecución en sí?) Intentará liberar el objeto por segunda vez.
Steven Fisher
¿Necesito enviar otros objetos de origen que creo cuando uso Mac OS 10.7?
p0lAris
Debe retener / liberar manualmente todos los objetos GCD en OS X 10.7.
Rob Mayoff
23

Solo un seguimiento aquí ... Si su objetivo de implementación mínimo es iOS 6, ARC ahora los administra.

kcharwood
fuente
Esto también se aplica a Mountain Lion. Si su objetivo de implementación es iOS 6 o Mountain Lion, no puede (de forma predeterminada) usar dispatch_release ya que es una macro que envía un mensaje de liberación al objeto que no está permitido bajo ARC.
Emil Eriksson