92

ARCNSStringからを取得する正しい方法を理解しようとしていますか? CFStringRef反対方向に行く場合も同じでCFStringRefNSStringARC に移動しますか?

メモリリークを発生させずにこれを行う正しい方法は何ですか?

4

1 に答える 1

186

通常

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_retainedCFRelease


それをまとめるために、あなたは持つことができます

NS文字列 → CF文字列

// 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`

CF文字列 → NS文字列

// 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;
于 2013-06-23T01:34:23.393 に答える