ARCNSString
からを取得する正しい方法を理解しようとしていますか? CFStringRef
反対方向に行く場合も同じでCFStringRef
、NSString
ARC に移動しますか?
メモリリークを発生させずにこれを行う正しい方法は何ですか?
ARCNSString
からを取得する正しい方法を理解しようとしていますか? CFStringRef
反対方向に行く場合も同じでCFStringRef
、NSString
ARC に移動しますか?
メモリリークを発生させずにこれを行う正しい方法は何ですか?
通常
NSString *yourFriendlyNSString = (__bridge NSString *)yourFriendlyCFString;
と
CFStringRef yourFriendlyCFString = (__bridge CFStringRef)yourFriendlyNSString;
__bridge
ここで、キーワードが存在する理由を知りたい場合は、 Apple のドキュメントを参照してください。そこには次のものがあります。
__bridge
所有権の譲渡なしで、Objective-C と Core Foundation の間でポインターを転送します。
__bridge_retained
またはCFBridgingRetain
、Objective-C ポインターを Core Foundation ポインターにキャストし、所有権をユーザーに譲渡します。オブジェクトの所有権を放棄するには、CFRelease または関連する関数を呼び出す必要があります。
__bridge_transfer
またはCFBridgingRelease
、Objective-C 以外のポインターを Objective-C に移動し、所有権を ARC に転送します。ARC は、オブジェクトの所有権を放棄する責任があります。
つまり、上記の場合、所有権を変更せずにオブジェクトをキャストしています。これは、どちらの場合も、文字列のメモリの処理を担当しないことを意味します。
何らかの理由で所有権を譲渡したい場合もあります。
たとえば、次のスニペットを考えてみましょう
- (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
}
このような場合はCFRelease
、キャスト時に所有権を譲渡して保存することをお勧めします。
- (void)sayHi {
CFStringRef str = CFStringCreateWithCString(NULL, "Hello World!", kCFStringEncodingMacRoman);
NSString * aNSString = (__bridge_transfer NSString *)str;
// or alternatively
NSString * aNSString = (NSString *)CFBridgingRelease(str);
NSLog(@"%@", aNSString);
}
の所有権str
が譲渡されたため、ARC が起動してメモリを解放します。
逆に、キャストを使用して a を a にNSString *
キャストできるため、オブジェクトを所有し、 を使用して明示的に解放する必要があります。CFString
__bridge_retained
CFRelease
それをまとめるために、あなたは持つことができます
// 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;