Sto cercando di capire il modo corretto di ottenere un NSStringda un CFStringRefin ARC? Lo stesso per andare nella direzione opposta, CFStringRefa NSStringin ARC?
Qual è il modo corretto per farlo senza creare perdite di memoria?
Sto cercando di capire il modo corretto di ottenere un NSStringda un CFStringRefin ARC? Lo stesso per andare nella direzione opposta, CFStringRefa NSStringin ARC?
Qual è il modo corretto per farlo senza creare perdite di memoria?
retaine releaserimuovendo oggetti, dobbiamo ora usare cast "belli" come __bridge_transfer, __unsafe_unretainede __autoreleasing. Nessuno non ha tempo per questo. (E seriamente, è più difficile da leggere. Secondo me, non ha facilitato affatto la gestione della memoria.)
Risposte:
Tipicamente
NSString *yourFriendlyNSString = (__bridge NSString *)yourFriendlyCFString;
e
CFStringRef yourFriendlyCFString = (__bridge CFStringRef)yourFriendlyNSString;
Ora, se vuoi sapere perché c'è la __bridgeparola chiave, puoi fare riferimento alla documentazione di Apple . Lì troverai:
__bridgetrasferisce un puntatore tra Objective-C e Core Foundation senza trasferimento di proprietà.
__bridge_retainedoppureCFBridgingRetainlancia un puntatore Objective-C a un puntatore Core Foundation e trasferisce anche la proprietà a te. Sei responsabile di chiamare CFRelease o una funzione correlata per rinunciare alla proprietà dell'oggetto.
__bridge_transferoCFBridgingReleasesposta un puntatore non-Objective-C su Objective-C e trasferisce anche la proprietà ad ARC. ARC è responsabile della rinuncia alla proprietà dell'oggetto.
Ciò significa che nei casi sopra si esegue il casting dell'oggetto senza modificare la proprietà. Ciò implica che in nessuno dei due casi sarai responsabile della gestione della memoria delle stringhe.
Potrebbe anche esserci il caso in cui desideri trasferire la proprietà per qualche motivo.
Ad esempio, considera il seguente frammento
- (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
}
in tal caso potresti voler salvare un CFReleasetrasferendo la proprietà durante la trasmissione.
- (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 proprietà di strè stata trasferita, quindi ora ARC entrerà in azione e rilascerà la memoria per te.
Al contrario, puoi lanciare un NSString *a CFStringusando un __bridge_retainedcast, in modo da essere proprietario dell'oggetto e dovrai rilasciarlo esplicitamente usando CFRelease.
Per concludere puoi avere
// 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`
// 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;
NSString->CFString, dovremmo usare __bridge. ma quando CFString->NSString, dovremmo usare __bride_transfer. ? E qualsiasi effetto collaterale, se lo usiamo CFReleasequando non ne abbiamo bisogno. grazie :)
CFReleasedovrebbe ragionevolmente mandare in crash il tuo programma, dal momento che finirai con un'operazione di conservazione / rilascio non corrispondente, rilasciando eventualmente un NULLpuntatore.
CFStringRef foo (__bridge CFStringRef)theNSString;eNSString *bar = (__bridge NSString *)theCFString;