Ahora mi pregunta es, ¿sigue siendo necesario establecer explícitamente las propiedades a cero en mi dealloc?
Sí, 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
.
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. –
@Patrick Me pregunto si puede lanzar su código de prueba (en Github Snippets o algo así). – adib
@adib Este código ya no funciona, ver [SO 9684972] (http://stackoverflow.com/questions/9274397) –