17

Recientemente comencé un nuevo proyecto usando conteo automático de referencias (ARC).
Cuando me asignaron el contenido de un CALayer:¿ARC funciona con objetos de gráficos básicos?

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

me dio un error

conversión implícita de un no-Objective-C tipo de puntero 'CGImageRef' a 'id' no está permitida con ARC

simplemente echando la CGImageRef-id esconde el error, pero me preguntaba si el arco sigue funcionando correctamente, entonces?

Respuesta

42

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

• Sesión 323 - Al presentar automática Referencia Contando

• Sesión 322 - Objective-C Los avances en Profundidad

Además, las notas de referencia 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 llamada gratuita Bridging"

En muchas aplicaciones Cocoa, es necesario utilizar objetos de estilo Fundación Core, ya sea desde el marco de la Fundación propio núcleo (tales como CFArrayRef o CFMutableDictionaryRef) o de marcos que adoptan convenciones de Core Foundation como Core Graphics (puede usar los tipos como CGColorSpaceRef y CGGradientRef).

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

Si lanzas entre los objetos de estilo Fundación Núcleo de Objective-C y, que necesidad de decirle al compilador acerca de la semántica de propiedad del objeto utilizando un molde (definido en objc/runtime.h) o un Core macro-estilo Fundación (definido en NSObject.h): [...]

Jörg Jacobsen tiene una buena visión general resumen de las opciones de puente, así: Managing Toll-free Bridging in an ARC’ed Environment.

__bridge_retained (n.b.: solo úselo cuando transfiera del puntero de objeto al puntero de tipo C): I (el programador) necesita hacer referencia a este objeto durante un tiempo en el mundo oscuro de punteros de tipo C, que es opaco a usted, ARC. Así que, por favor, no liberen este objeto mientras todavía lo necesito . I (el programador) promesa de liberar a mí mismo (en el mundo oscuro) cuando he terminado con ella

__bridge_transfer (NB: sólo lo uso cuando se lanza desde un puntero de tipo C para oponerse puntero): I (el programador) le entrego a usted, ARC, un objeto que yo poseo y que ya no estoy interesado en el mundo oscuro de punteros tipo C que es opaco para usted. Siempre que usted, ARC, sea hecho con ese objeto, libérelo usted mismo, porque conoce el justo a tiempo y así me ahorrará algo de trabajo sin tener que hacerlo yo mismo.

__bridge: ARC, a mantener el equilibrio de tu retiene y libera como sigo equilibrar las minas en el mundo oscuro de punteros de tipo C, que es .... Cada vez que necesite aferrarme a un objeto en el mundo oscuro, lo retendré y lo lanzaré cuando sea apropiado. No necesito ningún contrato extra con usted, ARC.

+0

extremadamente útil y completa respuesta, muchas gracias – Pieter

+0

:) ¡Gracias! ¡Me alegro de poder ayudar! Migramos una aplicación bastante grande que tenemos hace un par de días y nos tomó alrededor de dos días resolver todos los problemas, pero estoy bastante satisfecho con el resultado final. Mucho menos código, mucho más robusto. ARC es genial. Esos videos fueron un recurso increíble para mí. – Steve

+0

+1 por citar la explicación de Jorg Jacobsen. – jAckOdE

8

A pesar de las referencias señaladas por Steve, creo que el caso que muestra arriba puede ser especial. Desde el Transitioning to ARC Release Notes, prestar atención a la sección "El compilador Maneja CF objetos devueltos de los métodos de cacao":

El compilador entiende métodos Objective-C que devuelven Core tipos Fundación siguen las convenciones históricas Cacao de nombres (ver avanzada Guía de programación de administración de memoria). Por ejemplo, el compilador sabe que, en iOS, el CGColor devuelto por el método CGColor de UIColor no es propiedad.

El ejemplo de código que establecen lo siguiente:

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

se basa en la conocida retorno de CGColors de estos métodos (que se están perdiendo el elenco de Identificación del que he añadido en el código anterior, que debe ser corregido en su documentación pronto).

Como [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í.

4

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

Yo do =(__bridge id)image.CGImage.

+0

Recomiendo agregar formato de código a su respuesta, para mejorar la legibilidad. –

Cuestiones relacionadas