Estoy tratando de comprender la forma correcta de conseguir una NSStringde una CFStringRefde ARC? Lo mismo para ir en la dirección opuesta, CFStringRefa NSStringARC?
¿Cuál es la forma correcta de hacer esto sin crear pérdidas de memoria?
Estoy tratando de comprender la forma correcta de conseguir una NSStringde una CFStringRefde ARC? Lo mismo para ir en la dirección opuesta, CFStringRefa NSStringARC?
¿Cuál es la forma correcta de hacer esto sin crear pérdidas de memoria?
CFStringRef foo (__bridge CFStringRef)theNSString;yNSString *bar = (__bridge NSString *)theCFString;retaining yrelease-ing, ahora debemos usar moldes "hermosos" como__bridge_transfer,__unsafe_unretainedy__autoreleasing. Nadie no tiene tiempo para eso. (Y en serio, es más difícil de leer. En mi opinión, no facilitó la gestión de la memoria en absoluto).Respuestas:
Típicamente
NSString *yourFriendlyNSString = (__bridge NSString *)yourFriendlyCFString;y
CFStringRef yourFriendlyCFString = (__bridge CFStringRef)yourFriendlyNSString;Ahora, si quiere saber por qué la
__bridgepalabra clave está ahí, puede consultar la documentación de Apple . Allí encontrará:Lo que significa que en los casos anteriores estás lanzando el objeto sin cambiar la propiedad. Esto implica que en ningún caso serás el encargado de manejar la memoria de las cadenas.
También puede darse el caso de 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
CFReleasetransfiriendo la propiedad al transmitir.- (void)sayHi { CFStringRef str = CFStringCreateWithCString(NULL, "Hello World!", kCFStringEncodingMacRoman); NSString * aNSString = (__bridge_transfer NSString *)str; // or alternatively NSString * aNSString = (NSString *)CFBridgingRelease(str); NSLog(@"%@", aNSString); }Se
strha transferido la propiedad de , por lo que ahora ARC se activará y liberará la memoria por usted.Por otro lado, puedes lanzar un
NSString *aCFStringusando un__bridge_retainedyeso, de modo que serás dueño del objeto y tendrás que liberarlo explícitamente usandoCFRelease.Para envolverlo 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;fuente
NSString->CFString, deberíamos usar__bridge. pero cuandoCFString->NSStringdeberíamos usar__bride_transfer. ? Y cualquier efecto secundario, si lo usamosCFReleasecuando no lo necesitamos. gracias :)CFReleasedebería bloquear razonablemente su programa, ya que terminará con una operación de retención / liberación no coincidente, y eventualmente liberará unNULLpuntero.