objective-c nsstring automatic-ref-counting toll-free-bridging

objective c - NSString a CFStringRef y CFStringRef a NSString en ARC?



objective-c automatic-ref-counting (1)

Estoy tratando de entender la forma correcta de obtener un NSString de un CFStringRef en ARC? Lo mismo para ir en la dirección opuesta, CFStringRef a NSString en ARC?

¿Cuál es la forma correcta de hacer esto sin crear pérdidas de memoria?


Típicamente

NSString *yourFriendlyNSString = (__bridge NSString *)yourFriendlyCFString;

y

CFStringRef yourFriendlyCFString = (__bridge CFStringRef)yourFriendlyNSString;

Ahora, si quiere saber por qué la palabra clave __bridge está allí, puede consultar la documentación de Apple . Allí encontrarás:

__bridge transfiere un puntero entre Objective-C y Core Foundation sin transferencia de propiedad.

__bridge_retained o CFBridgingRetain lanza un puntero de Objective-C a un puntero de Core Foundation y también transfiere la propiedad a usted. Usted es responsable de llamar a CFRelease o una función relacionada para renunciar a la propiedad del objeto.

__bridge_transfer o CFBridgingRelease mueve un puntero no-Objective-C a Objective-C y también transfiere la propiedad a ARC. ARC es responsable de renunciar a la propiedad del objeto.

Lo que significa que en los casos anteriores está lanzando el objeto sin cambiar la propiedad. Esto implica que en ninguno de los casos estarás a cargo de manejar la memoria de las cuerdas.

También puede haber un caso en el que desee transferir la propiedad por algún motivo.

Por ejemplo, considere el siguiente fragmento

- (void)sayHi { CFStringRef str = CFStringCreateWithCString(NULL, "Hello World!", kCFStringEncodingMacRoman); NSString * aNSString = (__bridge NSString *)str; NSLog(@"%@", aNSString); CFRelease(str); //you have to release the string because you created it with a ''Create'' CF function }

en tal caso, es posible que desee guardar un CFRelease transfiriendo la propiedad al CFRelease del envío.

- (void)sayHi { CFStringRef str = CFStringCreateWithCString(NULL, "Hello World!", kCFStringEncodingMacRoman); NSString * aNSString = (__bridge_transfer NSString *)str; // or alternatively NSString * aNSString = (NSString *)CFBridgingRelease(str); NSLog(@"%@", aNSString); }

La propiedad de str ha sido transferida, por lo que ARC activará y liberará la memoria por usted.

Por otro lado, puedes convertir un NSString * en un CFString usando un molde __bridge_retained , de modo que serás el propietario del objeto y tendrás que liberarlo explícitamente mediante CFRelease .

Para concluir, puedes tener

NSString → CFString

// Don''t transfer ownership. You won''t have to call `CFRelease` CFStringRef str = (__bridge CFStringRef)string; // Transfer ownership (i.e. get ARC out of the way). The object is now yours and you must call `CFRelease` when you''re done with it CFStringRef str = (__bridge_retained CFStringRef)string // you will have to call `CFRelease`

CFString → NSString

// Don''t transfer ownership. ARC stays out of the way, and you must call `CFRelease` on `str` if appropriate (depending on how the `CFString` was created) NSString *string = (__bridge NSString *)str; // Transfer ownership to ARC. ARC kicks in and it''s now in charge of releasing the string object. You won''t have to explicitly call `CFRelease` on `str` NSString *string = (__bridge_transfer NSString *)str;