ARC prend-il en charge les files d'attente de distribution?

95

Je lis la documentation d'Apple sur la "Gestion de la mémoire pour les files d'attente d'envoi":

Même si vous implémentez une application garbage collection, vous devez toujours conserver et libérer vos files d'attente de répartition et autres objets de répartition. Grand Central Dispatch ne prend pas en charge le modèle de récupération de place pour la récupération de mémoire.

Je sais qu'ARC n'est pas un garbage collector mais j'aimerais être sûr que je n'ai pas besoin de dispatch_retain et dispatch_release mon dispatch_queue_t

flagg19
la source

Réponses:

234

La réponse courte: OUI, ARC conserve et libère les files d'attente de distribution.







Et maintenant pour la réponse longue…

Si votre cible de déploiement est inférieure à iOS 6.0 ou Mac OS X 10.8

Vous devez utiliser dispatch_retainet dispatch_releasesur votre file d'attente. L'ARC ne les gère pas.

Si votre cible de déploiement est iOS 6.0 ou Mac OS X 10.8 ou version ultérieure

ARC gérera votre file d'attente pour vous. Vous n'avez pas besoin (et ne pouvez pas) utiliser dispatch_retainou dispatch_releasesi ARC est activé.

Détails

À partir du SDK iOS 6.0 et du SDK Mac OS X 10.8, chaque objet de répartition (y compris a dispatch_queue_t) est également un objet Objective-C. Ceci est documenté dans le <os/object.h>fichier d' en- tête:

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

Cela signifie que vous pouvez stocker votre file d' attente dans un NSArrayou NSDictionary, ou dans une propriété avec l' un des strong, weak, unsafe_unretained, assignou retainattributs. Cela signifie également que si vous faites référence à votre file d'attente à partir d'un bloc, le bloc conservera automatiquement la file d'attente.

Ainsi, si votre cible de déploiement est au moins iOS 6.0 ou Mac OS X 10.8 et que ARC est activé , ARC conservera et libèrera votre file d'attente, et le compilateur signalera toute tentative d'utilisation dispatch_retainou dispatch_releasecomme une erreur.

Si votre cible de déploiement est au moins iOS 6.0 ou Mac OS X 10.8 et que ARC est désactivé , vous devez conserver et libérer manuellement votre file d'attente, soit en appelant dispatch_retainet dispatch_release, soit en envoyant la file d'attente retainet les releasemessages (comme [queue retain]et [queue release]).

Pour assurer la compatibilité avec les anciennes bases de code, vous pouvez empêcher le compilateur de voir votre file d'attente comme un objet Objective-C en définissant OS_OBJECT_USE_OBJCto 0. Par exemple, vous pouvez mettre ceci dans votre .pchfichier (avant toute #importinstruction):

#define OS_OBJECT_USE_OBJC 0

ou vous pouvez ajouter OS_OBJECT_USE_OBJC=0comme macro de préprocesseur dans vos paramètres de construction. Si vous définissez OS_OBJECT_USE_OBJCsur 0, ARC ne conservera ni ne libérera votre file d'attente pour vous, et vous devrez le faire vous-même en utilisant dispatch_retainet dispatch_release.

Rob Mayoff
la source
1
Notez, cependant, que la nouvelle modification désigne les objets de répartition comme des objets Objective-C. Ainsi, même si ARC est désactivé, ces objets seront automatiquement conservés s'ils sont capturés par un bloc - comme tous les autres objets Objective-C.
Jody Hagins
3
Il y a un cas de pointe intéressant. Si votre bibliothèque se déploie sur iOS 5.1 et votre application vers 6.0 et que vous utilisez ARC, vous devez dispatch_release et NULL l'objet dans votre dealloccode 5.1 . Sinon, quelque chose (code généré par le compilateur? Le runtime lui-même?) Tentera de libérer l'objet une seconde fois.
Steven Fisher
Dois-je envoyer d'autres objets source que je crée lorsque j'utilise Mac OS 10.7?
p0lAris
Vous devez conserver / libérer manuellement tous les objets GCD sous OS X 10.7.
rob mayoff
23

Juste un suivi ici ... Si votre cible de déploiement minimum est iOS 6, ARC les gère désormais.

Kcharwood
la source
Cela s'applique également à Mountain Lion. Si votre cible de déploiement est iOS 6 ou Mountain Lion, vous ne pouvez pas (par défaut) utiliser dispatch_release car il s'agit d'une macro qui envoie un message de libération à l'objet qui n'est pas autorisé sous ARC.
Emil Eriksson