ARC supporta le code di invio?


95

Sto leggendo la documentazione di Apple sulla "Gestione della memoria per le code di invio":

Anche se si implementa un'applicazione raccolta dati obsoleti, è comunque necessario conservare e rilasciare le code di invio e altri oggetti di invio. Grand Central Dispatch non supporta il modello di Garbage Collection per il recupero della memoria.

So che ARC non è un garbage collector ma vorrei essere sicuro di non aver bisogno di dispatch_retain e dispatch_release il mio dispatch_queue_t

Risposte:


234

La risposta breve: SÌ, ARC conserva e rilascia le code di invio.







E ora per la lunga risposta ...

Se l'obiettivo di distribuzione è inferiore a iOS 6.0 o Mac OS X 10.8

Devi usare dispatch_retaine dispatch_releasesulla tua coda. ARC non li gestisce.

Se la destinazione della distribuzione è iOS 6.0 o Mac OS X 10.8 o versioni successive

ARC gestirà la tua coda per te. Non è necessario (e non è possibile) utilizzare dispatch_retaino dispatch_releasese ARC è abilitato.

Dettagli

A partire da iOS 6.0 SDK e Mac OS X 10.8 SDK, ogni oggetto di invio (incluso a dispatch_queue_t) è anche un oggetto Objective-C. Questo è documentato nel <os/object.h>file di intestazione:

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

Questo significa che è possibile memorizzare la coda in una NSArrayo NSDictionary, oppure in una proprietà con una delle strong, weak, unsafe_unretained, assign, o retainattributi. Significa anche che se fai riferimento alla tua coda da un blocco, il blocco manterrà la coda automaticamente.

Quindi, se il tuo obiettivo di distribuzione è almeno iOS 6.0 o Mac OS X 10.8 e hai ARC abilitato , ARC manterrà e rilascerà la tua coda e il compilatore segnalerà qualsiasi tentativo di utilizzare dispatch_retaino dispatch_releasecome errore.

Se la destinazione di distribuzione è di almeno iOS 6.0 o Mac OS X 10.8, e si hanno ARC disattivato , è necessario trattenere e rilasciare la coda, manualmente o chiamando dispatch_retaine dispatch_release, o con l'invio di coda retaine releasedei messaggi (come [queue retain]e [queue release]).

Per compatibilità con i vecchi codebase, puoi impedire al compilatore di vedere la tua coda come un oggetto Objective-C definendo OS_OBJECT_USE_OBJCa 0. Ad esempio, puoi inserire questo nel tuo .pchfile (prima di qualsiasi #importistruzione):

#define OS_OBJECT_USE_OBJC 0

oppure puoi aggiungere OS_OBJECT_USE_OBJC=0come macro del preprocessore nelle impostazioni di build. Se si imposta OS_OBJECT_USE_OBJCa 0, ARC sarà non mantenere o rilasciare la coda per voi, e si dovrà fare da soli usando dispatch_retaine dispatch_release.


1
Notare, tuttavia, che la nuova modifica designa gli oggetti di spedizione come oggetti Objective-C. Pertanto, anche se ARC è disabilitato, questi oggetti verranno automaticamente trattenuti se catturati da un blocco, proprio come tutti gli altri oggetti Objective-C.
Jody Hagins

3
C'è un interessante caso limite. Se la tua libreria viene distribuita su iOS 5.1 e la tua app su 6.0 e stai usando ARC, devi dispatch_release e NULL l'oggetto nel tuo dealloccodice 5.1 . Altrimenti, qualcosa (codice generato dal compilatore? Il runtime stesso?) Proverà a rilasciare l'oggetto una seconda volta.
Steven Fisher

Devo inviare altri oggetti sorgente che creo quando utilizzo Mac OS 10.7?
p0lAris

È necessario conservare / rilasciare manualmente tutti gli oggetti GCD in OS X 10.7.
Rob Mayoff

23

Solo un seguito qui ... Se il tuo obiettivo di distribuzione minimo è iOS 6, ARC ora li gestisce.


Questo vale anche per Mountain Lion. Se il tuo obiettivo di distribuzione è iOS 6 o Mountain Lion, non puoi (per impostazione predefinita) utilizzare dispatch_release poiché si tratta di una macro che invia un messaggio di rilascio all'oggetto che non è consentito in ARC.
Emil Eriksson
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.