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 destino T. Si T es un tipo de puntero de objeto retenible, entonces op debe tener un tipo de puntero no retenible. Si T 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).

Author: Todd Lehman, 2011-08-12

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 alternativamente CFBridgingRelease(op) se usa para consumir un retain-count de un CFTypeRef mientras lo transfiere a ARC. Esto también podría estar representado por id someObj = (__bridge <NSType>) op; CFRelease(op);

  • (__bridge_retained <CFType>) op o alternativamente CFBridgingRetain(op) se usa para entregar un NSObject a CF-land mientras le da un +1 retain count. Debe manejar un CFTypeRef que cree de esta manera de la misma manera que manejaría un resultado de CFStringCreateCopy(). Esto también podría estar representado por CFRetain((__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.

 212
Author: monkeydom,
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

 52
Author: gregschlom,
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.

 32
Author: Brad Larson,
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