Saya mencoba memahami cara yang benar untuk mendapatkan NSString
dari a CFStringRef
di ARC? Sama untuk pergi ke arah sebaliknya, CFStringRef
ke NSString
dalam ARC?
Apa cara yang benar untuk melakukan ini tanpa menyebabkan kebocoran memori?
Saya mencoba memahami cara yang benar untuk mendapatkan NSString
dari a CFStringRef
di ARC? Sama untuk pergi ke arah sebaliknya, CFStringRef
ke NSString
dalam ARC?
Apa cara yang benar untuk melakukan ini tanpa menyebabkan kebocoran memori?
CFStringRef foo (__bridge CFStringRef)theNSString;
danNSString *bar = (__bridge NSString *)theCFString;
retain
ing danrelease
, sekarang kita harus menggunakan pemain "cantik" seperti__bridge_transfer
,__unsafe_unretained
dan__autoreleasing
. Tidak ada yang tidak punya waktu untuk itu. (Dan sungguh, ini lebih sulit untuk dibaca. Menurut saya, itu tidak memfasilitasi manajemen memori sama sekali.)Jawaban:
Khas
NSString *yourFriendlyNSString = (__bridge NSString *)yourFriendlyCFString;
dan
CFStringRef yourFriendlyCFString = (__bridge CFStringRef)yourFriendlyNSString;
Sekarang, jika Anda ingin tahu mengapa
__bridge
kata kunci itu ada, Anda bisa merujuk ke dokumentasi Apple . Di sana Anda akan menemukan:Artinya, dalam kasus di atas Anda mentransmisikan objek tanpa mengubah kepemilikan. Ini menyiratkan bahwa dalam kedua kasus Anda tidak akan bertanggung jawab untuk menangani memori string.
Mungkin juga ada kasus di mana Anda ingin mentransfer kepemilikan karena alasan tertentu.
Misalnya perhatikan cuplikan berikut
- (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 }
dalam kasus seperti itu, Anda mungkin ingin menyimpan
CFRelease
dengan mentransfer kepemilikan saat mentransmisi.- (void)sayHi { CFStringRef str = CFStringCreateWithCString(NULL, "Hello World!", kCFStringEncodingMacRoman); NSString * aNSString = (__bridge_transfer NSString *)str; // or alternatively NSString * aNSString = (NSString *)CFBridgingRelease(str); NSLog(@"%@", aNSString); }
Kepemilikan
str
telah ditransfer, jadi sekarang ARC akan masuk dan melepaskan memori untuk Anda.Sebaliknya, Anda dapat mentransmisikan a
NSString *
keCFString
menggunakan__bridge_retained
cast, sehingga Anda akan memiliki objek tersebut dan harus melepaskannya secara eksplisit dengan menggunakanCFRelease
.Untuk menyelesaikannya, Anda dapat memiliki
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;
sumber
NSString->CFString
, kita harus menggunakan__bridge
. tapi kapanCFString->NSString
, kita harus menggunakan__bride_transfer
. ? Dan efek sampingnya, jika kita gunakanCFRelease
saat kita tidak membutuhkannya juga. terima kasih :)CFRelease
seharusnya membuat program Anda mogok, karena Anda akan berakhir dengan operasi pertahankan / rilis yang tidak sesuai, yang akhirnya melepaskanNULL
penunjuk.