O ARC suporta filas de despacho?

95

Estou lendo a documentação da apple sobre "Gerenciamento de memória para filas de despacho":

Mesmo se você implementar um aplicativo com coleta de lixo, ainda deverá reter e liberar suas filas de despacho e outros objetos de despacho. O Grand Central Dispatch não oferece suporte ao modelo de coleta de lixo para recuperação de memória.

Eu sei que ARC não é um coletor de lixo, mas gostaria de ter certeza de que não preciso dispatch_retain e dispatch_release my dispatch_queue_t

flagg19
fonte

Respostas:

234

A resposta curta: SIM, o ARC retém e libera filas de despacho.







E agora a longa resposta ...

Se o seu destino de implantação for inferior a iOS 6.0 ou Mac OS X 10.8

Você precisa usar dispatch_retaine dispatch_releasena sua fila. A ARC não os gerencia.

Se o seu destino de implantação for iOS 6.0 ou Mac OS X 10.8 ou posterior

ARC gerenciará sua fila para você. Você não precisa (e não pode) usar dispatch_retainou dispatch_releasese o ARC estiver ativado.

Detalhes

A partir do iOS 6.0 SDK e do Mac OS X 10.8 SDK, cada objeto de envio (incluindo a dispatch_queue_t) também é um objeto Objective-C. Isso está documentado no <os/object.h>arquivo de cabeçalho:

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

Isto significa que você pode armazenar sua fila em uma NSArrayou NSDictionary, ou em uma propriedade com um dos strong, weak, unsafe_unretained, assign, ou retainatributos. Isso também significa que se você se referir à sua fila de um bloco, o bloco manterá a fila automaticamente.

Portanto, se seu destino de implantação for pelo menos iOS 6.0 ou Mac OS X 10.8 e você tiver o ARC habilitado , o ARC manterá e liberará sua fila e o compilador sinalizará qualquer tentativa de uso dispatch_retainou dispatch_releasecomo um erro.

Se o seu destino de implementação é de pelo menos iOS 6.0 ou Mac OS X 10.8, e você tem ARC desativado , você deve manter manualmente e liberar sua fila, quer chamando dispatch_retaine dispatch_release, ou enviando a fila retaine releasemensagens (como [queue retain]e [queue release]).

Para compatibilidade com bases de código antigas, você pode evitar que o compilador veja sua fila como um objeto Objective-C definindo OS_OBJECT_USE_OBJCpara 0. Por exemplo, você pode colocar isso em seu .pcharquivo (antes de quaisquer #importdeclarações):

#define OS_OBJECT_USE_OBJC 0

ou você pode adicionar OS_OBJECT_USE_OBJC=0como uma macro de pré-processador nas configurações de compilação. Se você definir OS_OBJECT_USE_OBJCcomo 0, o ARC não reterá ou liberará sua fila para você, e você terá que fazer isso sozinho usando dispatch_retaine dispatch_release.

rob mayoff
fonte
1
Observe, entretanto, que a nova mudança designa objetos de despacho como objetos Objective-C. Portanto, mesmo se o ARC estiver desabilitado, esses objetos serão retidos automaticamente se forem capturados por um bloco - assim como todos os outros objetos Objective-C.
Jody Hagins
3
Existe um caso interessante. Se sua biblioteca implanta no iOS 5.1 e seu aplicativo no 6.0 e você está usando o ARC, você precisa dispatch_release e NULL o objeto em seu dealloccódigo 5.1 . Caso contrário, algo (código gerado pelo compilador? O próprio tempo de execução?) Tentará liberar o objeto uma segunda vez.
Steven Fisher
Preciso enviar outros objetos de origem que criei ao usar o Mac OS 10.7?
p0lAris
Você deve reter / liberar manualmente todos os objetos GCD no OS X 10.7.
rob mayoff
23

Apenas um acompanhamento aqui ... Se o seu destino mínimo de implantação é iOS 6, o ARC agora os gerencia.

Kcharwood
fonte
Isso também se aplica ao Mountain Lion. Se o seu destino de implantação for iOS 6 ou Mountain Lion, você não pode (por padrão) usar dispatch_release, pois é uma macro que envia uma mensagem de liberação para o objeto que não é permitido pelo ARC.
Emil Eriksson,