web-dev-qa-db-fra.com

Quelle propriété dois-je utiliser pour une file d'attente de répartition après ARC?

Je gère une file d'attente de répartition en tant que propriété avec mon contrôleur de vue. Je crée cette file d'attente une fois dans la méthode init de mon contrôleur de vue et la réutilise plusieurs fois pour certaines tâches en arrière-plan. Avant ARC, je faisais ceci:

@property (nonatomic, assign) dispatch_queue_t filterMainQueue;

Et en init:

if (filterMainQueue == nil) {
     filterMainQueue = dispatch_queue_create("com.myQueue.CJFilterMainQueue", NULL);
}

Mais après ARC, je ne sais pas si cela devrait toujours être "assigné", ou s'il devrait être "fort" ou "faible". Le script du convertisseur ARC n'a rien changé mais je ne sais pas si un bug subtil vient du fait que cette file d'attente pourrait être désallouée pendant son utilisation?

Quelle serait la différence entre les 3 types de propriétés et qu'est-ce qui fonctionnera le mieux pour une file d'attente de répartition lors de l'utilisation d'ARC?

40
Z S

Réponse mise à jour:

Dans OS X et iOS actuels, les objets Dispatch sont désormais traités comme des objets Obj-C par ARC. Ils seront gérés en mémoire de la même manière que les objets Obj-C, et vous devez utiliser strong pour votre propriété.

Ceci est contrôlé par le OS_OBJECT_USE_OBJC macro, définie dans <os/object.h>. Il est défini sur 1 par défaut lorsque votre cible de déploiement est OS X 10.8 ou supérieur, ou iOS 6.0 ou supérieur. Si vous déployez sur un ancien système d'exploitation, cela reste à 0 et vous devriez voir ma réponse originale ci-dessous.


Réponse originale:

Les objets de répartition (y compris les files d'attente) ne sont pas des objets Obj-C, donc le seul choix possible est assign. Le compilateur générera une erreur si vous essayez d'utiliser strong ou weak. L'ARC n'a aucun impact sur GCD.

61
Lily Ballard

Voici comment définir la propriété dispatch_queue_t pour iOS 6.0 et supérieur ET inférieur à 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

Fondamentalement, OS_OBJECT_HAVE_OBJC_SUPPORT est défini comme 1 pour iOS 6.0 et supérieur. (MAC 10.8 et supérieur). Sous iOS 6, il est défini comme 0.

OS_OBJECT_HAVE_OBJC_SUPPORT définit que les objets OS comme GCD ont la prise en charge d'Objective C. L'ARC, la gestion de la mémoire, le comptage des références, etc. s'appliquent donc aux objets GCD.

9
Kris Subramanian

Voici ce que j'utilise:

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

Basé sur iOS7, j'ai testé si l'objet dispatch_queue est un objet objective-C et j'ai compris qu'il s'agissait déjà d'un objet objective-c. pour paraphraser cela, attribut ((NSObject)) n'est pas nécessaire maintenant.

4
Sungwook Kim

TL; DR: dispatch_queue_t est maintenant un objet Objective C et peut être géré avec ARC.

Je n'ai pas testé jusqu'où cela est vrai, mais en utilisant le SDK iOS 7 et Xcode 5, dispatch_queue_t est un type d'objet. Je déclare une propriété pour une file d'attente en tant que

@property (nonatomic, strong) dispatch_queue_t syncQueue;

Le compilateur est content et tout fonctionne comme prévu. Je sais définitivement que cela ne fonctionnait pas sous iOS 4 ou 5 (pré-ARC c'était retain au lieu de strong). J'ai creusé dans la définition de dispatch_queue_t et a trouvé ceci:

/*!
 * @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);

D'après les sons de cela, cela ne devrait pas fonctionner, donc j'ai vérifié la définition de DISPATCH_DECL et trouvé ceci, qui explique tout:

/*
 * 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.
 */
1
Holly