2012-02-14 11 views
12

(Xcode 4.2, iOS 5, ARC)Retenido Core Fundación Propiedad

tengo algunas propiedades de la Fundación Núcleo (/ Gráficos) objetos que deben tomar posesión de sus objetos. Ahora en estos Apple docs encontré esto:

En OS X v10.6 y posterior, puede utilizar la palabra clave __attribute__ para especificar que una propiedad Fundación Core debería ser tratado como un objeto Objective-C para la gestión de la memoria: @property(retain) __attribute__((NSObject)) CFDictionaryRef myDictionary;

Desafortunadamente no pude encontrar ninguna elaboración en esto. Estoy usando esto:

@property (nonatomic, strong) __attribute__((NSObject)) CGImageRef loupeImage;

Y parece que funciona de la manera que cabría esperar. Conserva el objeto al configurar la propiedad y la libera cuando establezco la propiedad en cero.

Ahora mi pregunta es, ¿aún tengo que establecer explícitamente esas propiedades en nulo en mi dealloc?

Respuesta

15

Editar: Mi publicación anterior fue incorrecta. __attribute__((NSObject)) en la propiedad solo hace que retenga/libere la propiedad al usar los descriptores de acceso a la propiedad. No afecta el acceso al ivar, y notablemente, no elimina (o libera) la propiedad en dealloc. Entonces sí, en su dealloc, debe decir self.loupeImage = nil; o debe decir [_loupeImage release].


Original post:

Si el compilador acepta la palabra clave strong, entonces va a tratar de manera correcta, la retención y la liberación como se esperaba, y nilling cabo automáticamente en ARC. La idea completa de __attribute__((NSObject)) es decirle al compilador que trate este objeto exactamente como si fuera un objeto obj-c, y eso es lo que hace.

Así que no, no debería tener que eliminarlos explícitamente en dealloc. Obtendrá el comportamiento de ARC predeterminado de nilling/releasing automáticamente.

+0

Me di cuenta de que también podría verificar esto con un pequeño código y de hecho es como usted dice, lo elimina automáticamente. –

+0

@Patrick Me pregunto si puede lanzar su código de prueba (en Github Snippets o algo así). – adib

+0

@adib Este código ya no funciona, ver [SO 9684972] (http://stackoverflow.com/questions/9274397) –

1

Ahora mi pregunta es, ¿sigue siendo necesario establecer explícitamente las propiedades a cero en mi dealloc?

, lo hace, con la declaración que mostró.

En el Property declarations section de la especificación ARC, que dice:

Aplicando __attribute__((NSObject)) a una propiedad, no de retainable tipo puntero de objeto tiene el mismo comportamiento que hace fuera del ARC: se requiere el tipo de propiedad de ser un tipo de puntero y permite el uso de modificadores que no sean assign.Estos modificadores solo afectan al getter y setter sintetizado ; los accesos directos al ivar (incluso si se sintetizó ) aún tienen semántica primitiva, y el valor en el ivar no se liberará automáticamente durante la desasignación.

(énfasis en la última parte añadida por mí)

En otras palabras, la aplicación de __attribute__((NSObject)) y strong en una propiedad con el tipo de fundación de la base hace que los captadores y definidores funcionan correctamente, pero no harán ARC gestionar el variable de instancia subyacente (porque el tipo de la variable de instancia seguirá siendo el tipo de Fundación básica) y, por lo tanto, ARC no lanzará la variable de instancia al dealloc si no es nula. Con dicha declaración de propiedad, deberá cancelarla en dealloc o provocar una fuga.

Sin embargo, hay una forma de hacer que ARC administre la variable en sí. Como la variable tiene un tipo de Fundación básica, puede convertirla en un tipo administrado por ARC envolviéndose en un typedef con __attribute__((NSObject)).

El Retainable object pointers section de la especificación ARC dice:

Hay tres clases de tipos de puntero objeto retainable:

  • punteros de bloque (formados mediante la aplicación de la intercalación (^) declarador sigilo a una tipo de función)
  • Punteros del objeto Objective-C (id, Class, NSFoo*, etc.)
  • typedefs marcados con __attribute__((NSObject))

(énfasis en el último elemento añadido por mí)

Así que si usted hace un typedef como esto:

typedef __attribute__((NSObject)) CGImageRef MyImageRef; 

y declara su propiedad como este:

@property (nonatomic, strong) MyImageRef loupeImage; 

la variable subyacente será administrada por ARC (porque la variable subyacente tendrá el tipo typedef 'd, que es un tipo gestionado por ARC) y no tendrá que anularlo en dealloc.

Cuestiones relacionadas