CFStringRefをNSStringに変換する方法は?


169
NSString *aNSString;
CFStringRef aCFString;
aCFString = CFStringCreateWithCString(NULL, [aNSString UTF8String], NSUTF8StringEncoding);
aCFString = CFXMLCreateStringByUnescapingEntities(NULL, aCFString, NULL);

NSStringから新しいものを入手するにはどうすればよいaCFStringですか?

回答:


349

NSStringとCFStringRefは「トールフリーブリッジ」であり、これらの間で単純に型キャストできます。

例えば:

CFStringRef aCFString = (CFStringRef)aNSString;

完全かつ透過的に機能します。同様に:

NSString *aNSString = (NSString *)aCFString;

以前の構文はMRC用でした。ARCを使用している場合、新しいキャスト構文は次のとおりです。

NSString *aNSString = (__bridge NSString *)aCFString;

同様に動作します。注意すべき重要な点は、CoreFoundationは参照カウントが+1のオブジェクトを返すことが多いということです。つまり、オブジェクトを解放する必要があります(すべてのCF [Type] Createフォーマット関数がこれを行います)。

Cocoaでは、自動解放または解放を安全に使用して解放することができます。


88
ARCを使用している場合、この場合の新しいキャスト構文はNSString * aNSString =(__bridge NSString *)aCFString
MikeG

6
MikeGに感謝します。逆の変換についても同様に行う必要がありました。NSString* str = @ "abc"; CFStringRef cstrref =(__ bridge CFStringRef)str;
KomodoDave 2012年

2
@NilObjectは、ARCを含めるように回答を更新してください。これにより、検索者がコメントを確認する必要がなくなります。ありがとう。
Dan Rosenstark、2012年

17

あなたは、Mac OS X / Objective Cの最近のバージョンでARCを使用している場合、それはです本当簡単:

NSString *happyString = (NSString *)CFBridgingRelease(sadString);

ただし、Xcodeは、NSStringへの無料のブリッジCFStringを試行しようとすると警告を表示し、CFBridgingRelease()で自動的にラップすることを提案します。オプションをクリックすると、ラッパーを受け入れて自動的に挿入させることができます。


3
よくわかりませんが、(__bridge NSString *)十分だと思いますCFBridgingRelease()。保持カウントをでインクリメントしても意味がありません。
・クール


4

実際には、Core FoundationオブジェクトのCocoaの保持、解放、自動解放を一般的に使用すべきではありません。ガベージコレクションを使用している場合(現時点ではMac OS Xのみ)、これらの保持、解放、自動解放の呼び出しはすべて何もしません。したがって、メモリリークが発生します。

アップルからhttp://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/GarbageCollection/Articles/gcCoreFoundation.html

Core FoundationとCocoaの非対称性を理解することが重要です。保持、リリース、および自動リリースは機能しません。たとえば、CFCreate…とreleaseまたはautoreleaseのバランスをとっている場合、ガベージコレクションされた環境でオブジェクトをリークします。

NSString *myString = (NSString *)CFStringCreate...(...);
// do interesting things with myString...
[myString release]; // leaked in a garbage collected environment

逆に、CFReleaseを使用して、以前に保持を使用して保持していたオブジェクトを解放すると、参照カウントのアンダーフローエラーが発生します。


PS:Peter Hoseyの回答についてコメントできないようです。不必要に自分のコメントを追加してしまいました。


3

型キャストだけでCFStringからNSStringに移行できるだけでなく、それ以外の方法でも機能することを付け加えておきます。CFStringCreateWithCStringメッセージをドロップできます。これは、後で解放する必要があるものの1つ少なくなります。(CFはCreateCocoaが使用する場所を使用するallocため、どちらの方法でも、リリースする必要がありました。)

結果のコード:

NSString *escapedString;
NSString *unescapedString = [(NSString *) CFXMLCreateStringByUnescapingEntities(NULL, (CFStringRef) escapedString, NULL) autorelease];

2

ARCとCFStringの保持数に問題がありました。少し調整してNilObjectsの回答を使用することは、私にとっては完璧に機能しました。保持した例を追加しました。

CFStringRef cfstringRef = (__bridge_retained  CFStringRef)aNsString;

0

あなたはそれをキャストする必要があります:

CFStringRef CFstringFileName=(__bridge CFStringRef)NSstringFileName;

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.