Con ARC, ya no puedo echar CGColorRef
a id
. Aprendí que necesito hacer un reparto en puente. Según los documentos de clang :
Un reparto en puente es un reparto de estilo C anotado con una de tres palabras clave:
(__bridge T) op
convierte el operando al tipo de destinoT
. SiT
es un tipo de puntero de objeto retenible,op
debe tener un tipo de puntero no retenible. SiT
es un tipo de puntero no retenible, op debe tener un tipo de puntero de objeto retenible. De lo contrario, el elenco está mal formado. No hay transferencia de propiedad y ARC no inserta operaciones de retención.
(__bridge_retained T) op
convierte el operando, que debe tener un tipo de puntero de objeto retenible, en el tipo de destino, que debe ser un tipo de puntero no retenible. ARC retiene el valor, sujeto a las optimizaciones habituales en valores locales, y el destinatario es responsable de equilibrar ese +1.
(__bridge_transfer T) op
convierte el operando, que debe tener un tipo de puntero no retenible, al tipo de destino, que debe ser un tipo de puntero de objeto retenible. ARC liberará el valor al final de la expresión completa adjunta, sujeto a las optimizaciones habituales en valores locales.Estos lanzamientos son necesarios para transferir objetos dentro y fuera del control ARC; vea la justificación en la sección sobre conversión de punteros de objetos retenibles.
Usando una
__bridge_retained
o__bridge_transfer
fundido puramente para convencer ARC para emitir retener o liberar una desequilibrada, respectivamente, es la falta de forma.
¿En qué tipo de situaciones usaría cada una?
Por ejemplo, CAGradientLayer
tiene una colors
propiedad que acepta una matriz de CGColorRef
s. Mi suposición es que debería usar __brige
aquí, pero no está claro exactamente por qué debería (o no debería).
fuente
Respuestas:
Estoy de acuerdo en que la descripción es confusa. Como acabo de comprenderlos, intentaré resumir:
(__bridge_transfer <NSType>) op
o, alternativamente,CFBridgingRelease(op)
se usa para consumir un conteo de retención de unCFTypeRef
tiempo mientras se transfiere a ARC. Esto también podría estar representado porid someObj = (__bridge <NSType>) op; CFRelease(op);
(__bridge_retained <CFType>) op
o, alternativamente,CFBridgingRetain(op)
se usa para entregar unaNSObject
tierra CF mientras le da un conteo de retención de +1. Debe manejar unaCFTypeRef
creación de esta manera de la misma manera que manejaría un resultadoCFStringCreateCopy()
. Esto también podría estar representado porCFRetain((__bridge CFType)op); CFTypeRef someTypeRef = (__bridge CFType)op;
__bridge
solo se lanza entre puntero-tierra y Objective-C object-land. Si no tiene inclinación a usar las conversiones anteriores, use esta.Quizás esto sea útil. Yo mismo, prefiero las
CFBridging…
macros bastante por encima de los modelos simples.fuente
Encontré otra explicación en la documentación de iOS que creo que es más fácil de entender:
__bridge
transfiere un puntero entre Objective-C y Core Foundation sin transferencia de propiedad.__bridge_retained (CFBridgingRetain)
lanza un puntero Objective-C a un puntero de Core Foundation y también le transfiere la propiedad.Usted es responsable de llamar a CFRelease o una función relacionada para renunciar a la propiedad del objeto.
__bridge_transfer (CFBridgingRelease)
mueve un puntero que no es Objective-C a Objective-C y también transfiere la propiedad a ARC.ARC es responsable de renunciar a la propiedad del objeto.
Fuente: Tipos puenteados gratuitos
fuente
Como continuación, en este caso específico, si está en iOS, Apple recomienda usar UIColor y su
-CGColor
método para devolver el CGColorRef alcolors
NSArray. En las Notas de lanzamiento de Transición a ARC , en la sección "El compilador maneja los objetos CF devueltos de los métodos de cacao", se indica que utilizando un método como-CGColor
el compilador manejará automáticamente el que devuelve un objeto Core Foundation.Por lo tanto, sugieren usar código como el siguiente:
Tenga en cuenta que a partir de ahora, al código de ejemplo de Apple le falta el elenco (id) que tengo arriba, que todavía es necesario para evitar un error del compilador.
fuente