2011-11-03 19 views
18

He convertido mi aplicación para usar ARC.- [No es un tipo retener]: mensaje enviado a la instancia desasignada

Antes de que tuviera la siguiente línea de código:

NSArray *colors = [NSArray arrayWithObjects:startColor, endColor, nil]; 

Desde la conversión implícita de un-C fuera del objetivo de tipo puntero a 'id' no está permitida con ARC, me volvió a escribir la línea como la siguiente:

NSArray *colors = [NSArray arrayWithObjects:(__bridge id)startColor, (__bridge id)endColor, nil]; 

Todo funciona bien en el simulador, sin embargo, en el dispositivo de la aplicación se bloquea en la mencionada línea con el mensaje de error:

-[Not A Type retain]: message sent to deallocated instance 

¿Alguna idea de cómo solucionarlo?

+0

¿de qué tipos es su variable? el código circundante estaría bien para determinar si necesita '__bridge',' __bridge_retained' o '__bridge_transfer' –

+0

Los tipos de las variables son CGColorRef. No estoy seguro de lo que quiere decir con "código circundante", pero probé las 3 versiones de "puente", pero el problema persiste. – Gytis

+0

¿cómo se crea el CGColorRef? ¿Lo lanzas? ... –

Respuesta

30

Este puente fundido puede no funcionar, como se describe en hatfinch his answer here, debido a que el CGColorRef regresó de -CGColor no puede colgar alrededor después de su última referencia a la UIColor que lo genera. Pensé que se trataba de un error, basado en la discusión en this Apple developer forum thread, pero era una mala interpretación de cómo administrar la vida útil de estos CGColorRefs.

Una forma en que esto funcionará es usar el puente integrado provisto por el método -CGColor en UIColor. En lugar de guardar fuera de su CGColor a una variable temporal como lo hace arriba, debería ser capaz de usar algo como lo siguiente:

NSArray *colors = [NSArray arrayWithObjects:(id)[color1 CGColor], 
              (id)[color2 CGColor], nil]; 

con color1 y color2 siendo UIColor casos.

El puenteo se ocupa de usted por el método -CGColor, de acuerdo con la sección "El compilador maneja los objetos de CF devueltos por los métodos del cacao" del Transitioning to ARC Release Notes. En la documentación falta el elenco a la identificación que tengo arriba, que es necesario para que esto se compile.

He probado esto, y parece funcionar en mi caso, coincidiendo con lo que informa Ben en el hilo de foros de desarrollador vinculado anteriormente.

Además de lo anterior, se puede retener de forma explícita y liberar los CGColorRefs volvió del método -CGColor y superarlas a través de su NSArray, de nuevo como hatfinch muestra here.

+0

Eso es correcto. Yo mismo había resuelto este problema de la misma manera, pero no pude responder a mi propia pregunta debido a la restricción de StackOverflow (respondiendo a su propia pregunta varias horas después de publicarla). ¡Gracias! – Gytis

+1

Me salvaste el día. He estado rasgándome el cabello por horas por esto. –

+1

Gracias a ti, ¡no tuve que arrancarme el pelo como Jason! – NickDK

0

Edit:
Si utiliza la propiedad CGColor de UIColor, el CGColor desaparecerá en el momento de la última referencia a la instancia de UIColor. Para evitar esto, "puente" sus colores directamente en la llamada de función:

NSArray *colors = [NSArray arrayWithObjects:[uiStartColor CGColor], [uiEndColor CGColor], nil]; 

Este método se describe en Apple's documentation

original:
intente asignar una variable: id color = (__bridge_transfer id)CGColorCreate(...); y no hacer nada más con el retorno directo valor de CGColorCreate()

+0

Intenté 'id color = (__bridge_transfer id) CGColorCreateCopy (...);' sin embargo no ayuda – Gytis

0

Gracias @Brad por la punta de -CGColor!

mi aplicación se bloquea en la línea siguiente, que será invocada por un objeto NSInvocation.

CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); 

la solución está definiendo una propiedad de color y utilícela en su lugar.

@property(strong, nonatomic) UIColor *backgroundColor; 
    ...... 
    self.backgroundColor = [UIColor whiteColor]; 
    ...... 
    CGContextSetFillColorWithColor(context, self.backgroundColor.CGColor); 
Cuestiones relacionadas