NSString *aNSString;
CFStringRef aCFString;
aCFString = CFStringCreateWithCString(NULL, [aNSString UTF8String], NSUTF8StringEncoding);
aCFString = CFXMLCreateStringByUnescapingEntities(NULL, aCFString, NULL);
NSString
から新しいaCFString
を取得するにはどうすればよいですか?
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-Free Bridged Types 」を参照してください。
実際には、一般的にCore FoundationオブジェクトでCocoaの保持、リリース、自動リリースを使用しないでください。 Garbage Collectionを使用している場合(現時点ではMac OS Xのみ)、retain、release、autoreleaseの呼び出しはすべてノーオペレーションです。したがって、メモリリークが発生します。
Core FoundationとCocoaの非対称性を理解することは重要です。Retain、Release、およびAutoreleaseはノーオペレーションです。たとえば、CFCreate…をリリースまたは自動リリースとバランスさせた場合、ガベージコレクション環境でオブジェクトをリークします。
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;