objective c - ¿Qué propiedad debo usar para una cola de envío después de ARC?
objective-c automatic-ref-counting (5)
Así es como se definiría la propiedad dispatch_queue_t para iOS 6.0 y superior Y debajo de iOS 6.0
#if OS_OBJECT_HAVE_OBJC_SUPPORT == 1
@property (nonatomic, strong) dispatch_queue_t serialDispatchQueue;
#else
@property (nonatomic, assign) dispatch_queue_t serialDispatchQueue;
#endif
Básicamente OS_OBJECT_HAVE_OBJC_SUPPORT se define como 1 para iOS 6.0 y superior. (MAC 10.8 y superior). Debajo de iOS 6 se define como 0.
OS_OBJECT_HAVE_OBJC_SUPPORT define que los objetos del sistema operativo como GCD tienen soporte para el objetivo C. Así que ARC, gestión de memoria, recuento de referencias, etc. se aplica a los objetos GCD.
Mantengo una cola de distribución como propiedad con mi controlador de vista. Creo esta cola una vez en el método init de mi controlador de vista, y la reutilizo varias veces para algunas tareas en segundo plano. Antes de ARC, estaba haciendo esto:
@property (nonatomic, assign) dispatch_queue_t filterMainQueue;
Y en init:
if (filterMainQueue == nil) {
filterMainQueue = dispatch_queue_create("com.myQueue.CJFilterMainQueue", NULL);
}
Pero después de ARC, no estoy seguro si esto todavía debe ser "asignar", o debería ser "fuerte" o "débil". La secuencia de comandos del convertidor ARC no cambió nada, pero no estoy seguro de si un error sutil proviene del hecho de que esta cola podría ser desasignada mientras se está utilizando.
¿Cuál sería la diferencia entre los 3 tipos de propiedades y qué funcionaría mejor para una cola de envío cuando se usa ARC?
Basado en iOS7, probé si el objeto dispatch_queue es un objeto Object-C y me di cuenta de que ya son object-object. parafraseando esto, el atributo ((NSObject)) no es necesario ahora.
Esto es lo que uso:
@property (readwrite, strong, nonatomic) __attribute__((NSObject)) dispatch_queue_t queue;
Respuesta actualizada:
En el sistema operativo actual X e iOS, los objetos de envío se tratan ahora como objetos Obj-C por ARC. Serán administrados por memoria de la misma manera que los Objetos Obj-C lo harán, y deberías usar objetos strong
para tu propiedad.
Esto está controlado por la macro OS_OBJECT_USE_OBJC
, definida en <os/object.h>
. Se establece en 1
de forma predeterminada cuando su destino de despliegue es OS X 10.8 o superior, o iOS 6.0 o superior. Si se está implementando en un sistema operativo anterior, este se deja en 0
y debería ver mi respuesta original a continuación.
Respuesta original:
Los objetos de envío (incluidas las colas) no son objetos Obj-C, por lo que la única opción posible es assign
. El compilador arrojará un error si intenta usar strong
o weak
. ARC no tiene impacto en GCD.
TL; DR: dispatch_queue_t
es ahora un objeto Objective C y se puede administrar con ARC.
No he probado cuánto tiempo atrás esto es cierto, pero usando iOS 7 SDK y Xcode 5, dispatch_queue_t
es un tipo de objeto. Estoy declarando una propiedad para una cola como
@property (nonatomic, strong) dispatch_queue_t syncQueue;
El compilador está contento y todo funciona como se esperaba. Sé definitivamente que esto no solía funcionar en iOS 4 o 5 (antes de ARC era retain
lugar de strong
). Busqué en la definición de dispatch_queue_t
y encontré esto:
/*!
* @typedef dispatch_queue_t
*
* @abstract
* Dispatch queues invoke blocks submitted to them serially in FIFO order. A
* queue will only invoke one block at a time, but independent queues may each
* invoke their blocks concurrently with respect to each other.
*
* @discussion
* Dispatch queues are lightweight objects to which blocks may be submitted.
* The system manages a pool of threads which process dispatch queues and
* invoke blocks submitted to them.
*
* Conceptually a dispatch queue may have its own thread of execution, and
* interaction between queues is highly asynchronous.
*
* Dispatch queues are reference counted via calls to dispatch_retain() and
* dispatch_release(). Pending blocks submitted to a queue also hold a
* reference to the queue until they have finished. Once all references to a
* queue have been released, the queue will be deallocated by the system.
*/
DISPATCH_DECL(dispatch_queue);
Por el sonido de eso, no debería funcionar, así que revisé la definición de DISPATCH_DECL
y encontré esto, que explica todo:
/*
* By default, dispatch 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.
* See <os/object.h> for details.
*/