NSString a CFStringRef y CFStringRef a NSString en ARC?

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 (ie 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; 
Intereting Posts