¿ARC funciona con objetos de Core Graphics?

Recientemente comencé un nuevo proyecto usando el conteo automático de referencias (ARC).
Cuando asigné los contenidos de un CALayer:

UIView* view = ... UIImage* image = ... view.layer.contents = image.CGImage 

Recibí un error

La conversión implícita de un puntero no-Objective-C tipo ‘CGImageRef’ a ‘id’ no se permite con ARC

El simple hecho de CGImageRef en id oculta el error, pero me preguntaba si el ARC todavía funciona correctamente.

Deberías echar un vistazo a los videos de ARC de WWDC 2011. Están disponibles en el sitio del desarrollador y se abren a través de iTunes. Especialmente:

• Sesión 323: introducción del recuento automático de referencias

• Sesión 322 – Avances de Objective-C en profundidad

Además, las notas de referencia de ARC:

https://developer.apple.com/library/content/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html

Tanto las notas de referencia como los videos analizan Core Graphics (et al) y cómo funcionan con ARC.

Específicamente, mira la sección llamada “Gestión de puentes sin costo”

En muchas aplicaciones de Cocoa, necesita utilizar objetos del estilo de Core Foundation, ya sea desde el propio Framework Core Foundation (como CFArrayRef o CFMutableDictionaryRef) o desde frameworks que adoptan convenciones de Core Foundation como Core Graphics (puede usar tipos como CGColorSpaceRef y CGGradientRef )

El comstackdor no administra automáticamente las vidas de los objetos de Core Foundation; debe llamar a CFRetain y CFRelease (o las variantes correspondientes específicas de tipo) según lo dicten las reglas de administración de memoria de Core Foundation (consulte la Guía de progtwigción de administración de memoria para Core Foundation).

Si elige entre Objective-C y Core Foundation-style, necesita decirle al comstackdor sobre la semántica de propiedad del objeto utilizando un molde (definido en objc / runtime.h) o una macro de estilo Core Foundation (definida en NSObject.h): […]

Jörg Jacobsen también tiene un buen resumen general de las opciones de puente: gestión de puentes sin cargo en un entorno ARC .

__bridge_retained (nb: solo utilícelo cuando se convierte desde puntero de objeto a puntero de tipo C): I (el progtwigdor) necesita hacer referencia a este objeto durante un tiempo en el mundo oscuro de los punteros de tipo C, que es opaco para usted, ARC. Entonces, por favor, no liberen este objeto mientras lo necesite. Yo (el progtwigdor) prometo liberarlo yo mismo (en el mundo oscuro) cuando termine con esto

__bridge_transfer (nb: solo utilícelo cuando transfiere del puntero de tipo C al puntero del objeto): I (el progtwigdor) le entrego a usted, ARC, un objeto que poseo y que ya no me interesa en el mundo oscuro del tipo C punteros que son opacos para usted. Siempre que usted, ARC, termine con ese objeto, libérelo usted mismo, porque conoce el momento adecuado y así me ahorrará trabajo sin tener que hacerlo yo mismo.

__bridge : ARC, sigues equilibrando tus retiros y lanzamientos mientras sigo equilibrando los míos en el mundo oscuro de los punteros tipo C, que es … Cada vez que necesito aferrarme a un objeto en el mundo oscuro lo retendré yo mismo y lo liberaré cuando sea apropiado. No necesito ningún contrato adicional con usted, ARC.

A pesar de las referencias señaladas por Steve, creo que el caso que muestra arriba podría ser especial. Desde la Transición a las Notas de versión de ARC , preste atención a la sección “El comstackdor maneja los objetos de CF devueltos por los métodos de cocoa”:

El comstackdor entiende los métodos de Objective-C que devuelven los tipos básicos de Foundation siguen las convenciones históricas de nombres de Cocoa (consulte la Guía de progtwigción avanzada de administración de memoria). Por ejemplo, el comstackdor sabe que, en iOS, el CGColor devuelto por el método CGColor de UIColor no es propiedad.

El ejemplo de código que proporcionan:

 gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor darkGrayColor] CGColor], (id)[[UIColor lightGrayColor] CGColor], nil]; 

se basa en la devolución conocida de CGColors de estos métodos (les falta el elenco a la identificación que he agregado en el código anterior, que debería corregirse en su documentación próximamente).

Debido a que [image CGImage] sigue las convenciones de nomenclatura, creo que CGImage se enlazará correctamente aquí. Creo que tu elenco a ID debería ser todo lo que necesitas aquí.

Una respuesta popular a layer.contents = (id)image.CGImage pregunta es layer.contents = obj_unretainedObject(image.CGImage) .

I do =(__bridge id)image.CGImage .