Propiedad de la Fundación Retained Core

(Xcode 4.2, iOS 5, ARC )

Tengo algunas properties de los objects Core Foundation (/ Graphics) que deberían tomar posession de sus objects. Ahora en estos documentos de Apple encontré esto:

En OS X v10.6 y posterior, puede usar la palabra key __attribute__ para especificar que una propiedad de Core Foundation se deba tratar como un object Objective-C para administración de memory: @property(retain) __attribute__((NSObject)) CFDictionaryRef myDictionary;

Desafortunadamente, no pude encontrar ninguna explicación sobre esto. Estoy usando esto:

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

Y parece funcionar como esperaba. Conserva el object al establecer la propiedad y la libera cuando configuro la propiedad a cero.

Ahora mi pregunta es, ¿todavía necesito establecer explícitamente esas properties a cero en mi desocupación?

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


Publicación original:

Si el comstackdor acepta la palabra key strong , lo tratará correctamente, reteniendo y liberando como se esperaba, y seleccionando automáticamente en ARC. La idea completa de __attribute__((NSObject)) es que le dice al comstackdor que trate este object exactamente como si fuera un object obj-c, y eso es lo que hace.

Entonces, no, no deberías tener que explotarlos explícitamente en Dealloc. Obtendrá el comportamiento pnetworkingeterminado de ARC de nilling / releasing automáticamente.

Ahora mi pregunta es, ¿todavía necesito establecer explícitamente esas properties a cero en mi desocupación?

, lo haces, con la statement que mostraste.

En la sección Declaraciones de properties de la especificación ARC, dice:

La aplicación de __attribute__((NSObject)) a una propiedad que no sea de tipo puntero object retenedor tiene el mismo comportamiento que se realiza fuera de ARC: requiere que el tipo de propiedad sea algún tipo de puntero y permite el uso de modificadores distintos de assign . Estos modificadores solo afectan al getter y setter sintetizado; los accesos directos al ivar (incluso si se sintetizan) aún tienen una semántica primitiva, y el valor en el ivar no se liberará automáticamente durante la desasignación .

(énfasis en la última parte agregada por mí)

En otras palabras, aplicar __attribute__((NSObject)) y strong en una propiedad con el tipo de Core Foundation hace que los getters y setters funcionen correctamente, pero no hará que ARC administre la variable de instancia subyacente (porque el tipo de variable de instancia seguirá siendo el Core Tipo de base) y, por lo tanto, ARC no liberará la variable de dealloc cuando se encuentre dealloc si no es nula. Con dicha statement de properties, tendrá que dealloc en dealloc o causar una fuga.

Sin embargo, hay una manera de hacer que ARC administre la variable misma. Como la variable tiene un tipo de base de núcleo, puede convertirlo en un tipo de gestión ARC envolviéndolo en un typedef con __attribute__((NSObject)) .

La sección Punteros de objects retenibles de la especificación ARC dice:

Hay tres types de types de pointers de object retenibles:

  • pointers de bloque (formados mediante la aplicación del sigilo del declarante de cursor ( ^ ) a un tipo de function)
  • Objective-C pointers object ( id , Class , NSFoo* , etc.)
  • typedefs marcados con __attribute__((NSObject))

(énfasis en el último artículo agregado por mí)

Entonces si hace un typedef así:

 typedef __attribute__((NSObject)) CGImageRef MyImageRef; 

y declara tu propiedad así:

 @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 administrado por ARC) y no tendrás que dealloc en dealloc .