ARCO y puente de fundición
Con ARC, ya no puedo lanzar CGColorRef
a id
. Aprendí que necesito hacer un yeso puenteado. Según clang docs :
A bridged cast es un elenco de estilo C anotado con una de tres palabras clave:
(__bridge T) op
lanza el operando al tipo de destinoT
. SiT
es un tipo de puntero de objeto retenible, entoncesop
debe tener un tipo de puntero no retenible. SiT
es un tipo de puntero no retenible, entonces op debe tener un objeto retenible tipo de puntero. De lo contrario el reparto está mal formado. No hay transferencia de propiedad, y ARC inserta no retén las operaciones.
(__bridge_retained T) op
lanza el operando, que debe tener tipo de puntero de objeto retenible, al tipo de destino, que debe ser un tipo de puntero no retenible. ARC retiene el valor, sujeto a la optimizaciones habituales en valores locales, y el destinatario es responsable para equilibrar eso +1.
(__bridge_transfer T) op
lanza el operando, que debe tener no retenible tipo de puntero, 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 que encierra, sujeto a las optimizaciones habituales sobre los valores locales.Estos moldes son necesarios para transferir objetos dentro y fuera de Control de arco; vea la justificación en la sección sobre conversión de punteros de objetos retenibles.
Usando un
__bridge_retained
o__bridge_transfer
lanzado puramente para convencer ARCO para emitir una retención desequilibrada o liberación, respectivamente, es pobre forma.
¿En qué tipo de situaciones usaría cada una?
Por ejemplo, CAGradientLayer
tiene una propiedad colors
que acepta una matriz de CGColorRef
s. Mi conjetura es que debería usar __brige
aquí, pero no está claro exactamente por qué debería (o no debería).
3 answers
Estoy de acuerdo en que la descripción es confusa. Ya que acabo de entenderlos, voy a tratar de resumir:
(__bridge_transfer <NSType>) op
o alternativamenteCFBridgingRelease(op)
se usa para consumir un retain-count de unCFTypeRef
mientras lo transfiere a ARC. Esto también podría estar representado porid someObj = (__bridge <NSType>) op; CFRelease(op);
(__bridge_retained <CFType>) op
o alternativamenteCFBridgingRetain(op)
se usa para entregar unNSObject
a CF-land mientras le da un +1 retain count. Debe manejar unCFTypeRef
que cree de esta manera de la misma manera que manejaría un resultado deCFStringCreateCopy()
. Esto también podría estar representado porCFRetain((__bridge CFType)op); CFTypeRef someTypeRef = (__bridge CFType)op;
__bridge
solo lanza entre pointer-land y Objective-C object-land. Si no tienes inclinación a usar las conversiones anteriores, usa esta.
Tal vez esto sea útil. Yo mismo, prefiero las macros CFBridging…
bastante sobre los moldes simples.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-03 20:53:31
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 Core Foundation y también te transfiere la propiedad.Usted es responsable de llamar a CFRelease o a una función relacionada para renunciar a la propiedad del objeto.
-
__bridge_transfer (CFBridgingRelease)
moves a non-Objective-C pointer to Objective-C and also transfers ownership to ARC.ARC es responsable de renunciar a la propiedad del objeto.
Fuente: Tipos de Puentes Gratuitos
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-15 14:46:29
Como continuación, en este caso específico, si está en iOS, Apple recomienda usar UIColor y su método -CGColor
para devolver el CGColorRef en el colors
NSArray. En el Transitioning to ARC Release Notes, bajo la sección "The Compiler Handles CF Objects Returned From Cocoa Methods", se indica que usando un método como -CGColor
que devuelve un objeto Core Foundation será automáticamente manejado correctamente por el compilador.
Por lo tanto, sugieren el uso de código como el siguiente:
CAGradientLayer *gradientLayer = (CAGradientLayer *)[self layer];
gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor darkGrayColor] CGColor],
(id)[[UIColor lightGrayColor] CGColor], nil];
Tenga en cuenta que a partir de ahora, el código de ejemplo de Apple le falta el cast (id) que tengo arriba, que todavía es necesario para evitar un error del compilador.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-18 03:28:57