CFStringRefをNSStringに変換する方法は?
質問
NSString *aNSString;
CFStringRef aCFString;
aCFString = CFStringCreateWithCString(NULL, [aNSString UTF8String], NSUTF8StringEncoding);
aCFString = CFXMLCreateStringByUnescapingEntities(NULL, aCFString, NULL);
aCFString
から新しい NSString
を取得するにはどうすればよいですか?
解決
NSStringとCFStringRefは「Toll free bridged」です。つまり、単純に型キャストできます。
例:
CFStringRef aCFString = (CFStringRef)aNSString;
完全かつ透過的に機能します。同様に:
NSString *aNSString = (NSString *)aCFString;
以前の構文はMRC向けでした。 ARCを使用している場合、新しいキャスト構文は次のとおりです。
NSString *aNSString = (__bridge NSString *)aCFString;
も機能します。注意すべき重要な点は、CoreFoundationは参照カウントが+1のオブジェクトを返すことが多いため、解放する必要があることを意味します(すべてのCF [Type] Create形式関数がこれを行います)。
良い点は、Cocoaでは自動解放または解放を使用して安全に解放できることです。
他のヒント
最近のバージョンのMac OS X / Objective CでARCを使用している場合、 本物は簡単です:
NSString *happyString = (NSString *)CFBridgingRelease(sadString);
ただし、無料のブリッジをしようとすると、Xcodeは喜んで警告します CFStringをNSStringに変換し、CFBridgingRelease()で自動的にラップすることを提案します。 このオプションをクリックすると、受け入れて自動的にラッパーを挿入することができます。
これらは同等であるため、CFStringRefをキャストできます。
NSString *aNSString = (NSString*)aCFString;
詳細については、 Toll-無料のブリッジタイプ。
実際には、一般的にCore FoundationオブジェクトでCocoaの保持、リリース、自動リリースを使用しないでください。 Garbage Collectionを使用している場合(現時点ではMac OS Xのみ)、retain、release、autoreleaseの呼び出しはすべてノーオペレーションです。したがって、メモリリークが発生します。
Core FoundationとCocoaの非対称性を理解することは重要です。そこでは、保持、リリース、自動リリースは何もしません。たとえば、CFCreate…のバランスが取れている場合、 releaseまたはautoreleaseを使用すると、ガベージコレクション環境でオブジェクトがリークされます。
NSString *myString = (NSString *)CFStringCreate...(...);
// do interesting things with myString...
[myString release]; // leaked in a garbage collected environment
逆に、CFReleaseを使用して、retainを使用して以前に保持したオブジェクトを解放すると、参照カウントアンダーフローエラーが発生します。
PS:Peter Hoseyの回答にコメントできないようです。不必要に自分のコメントを追加して申し訳ありません。
型キャストのみでCFStringからNSStringに移動できるだけでなく、他の方法でも機能することを追加します。 CFStringCreateWithCString
メッセージをドロップできます。これは、後でリリースする必要があるものの1つです。 (CFは Create
を使用しますが、Cocoaは alloc
を使用します。どちらにしても、リリースする必要があります。)
結果のコード:
NSString *escapedString;
NSString *unescapedString = [(NSString *) CFXMLCreateStringByUnescapingEntities(NULL, (CFStringRef) escapedString, NULL) autorelease];
ARCとCFStringの保持カウントに問題がありました。 NilObjectsの答えを少し調整して使用することは、私にとって完璧に機能しました。私はちょうど保持を追加しました。
CFStringRef cfstringRef = (__bridge_retained CFStringRef)aNsString;
キャストする必要があります:
CFStringRef CFstringFileName=(__bridge CFStringRef)NSstringFileName;
:With CFStringRef idc;を使用できます。
NSString *sId = [NSString stringWithFormat:@"%@", (NSString*)idc];