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를 사용하는 경우,이 경우에 대한 새로운 주조 구문은 이제 * aNSString = (__bridge있는 NSString *) aCFString있는 NSString한다
MikeG

6
MikeG에게 감사합니다. 리버스 변환을 위해 비슷한 작업을 수행해야했습니다. NSString * str = @ "abc"; CFStringRef cstrref = (__ 브리지 CFStringRef) str;
KomodoDave

2
@NilObject는 ARC를 포함하도록 답변을 업데이트하여 검색자가 주석을 확인할 필요가 없도록하십시오. 감사.
Dan Rosenstark

17

최신 버전의 Mac OS X / Objective C에서 ARC를 사용하는 경우 정말 쉽습니다.

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

그러나 Xcode는 브리지 CFString을 NSString에 유료로 연결하고 CFBridgingRelease ()로 자동 줄 바꿈하려고 할 때 행복하게 경고합니다.이 옵션을 클릭하면 래퍼를 수락하고 자동으로 래퍼를 삽입 할 수 있습니다.


3
확실하지 않지만 (__bridge NSString *)충분 하다고 생각 합니다.로 유지 횟수를 증가시킬 점이 없습니다 CFBridgingRelease().
Cœur


4

실제로, 일반적으로 Core Foundation 객체에서 Cocoa retain, release, autorelease를 사용해서는 안됩니다. 가비지 수집을 사용하는 경우 (현재는 Mac OS X에서만) 유지, 해제, 자동 해제 호출은 모두 작동하지 않습니다. 따라서 메모리 누수가 발생합니다.

Apple http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/GarbageCollection/Articles/gcCoreFoundation.html에서 :

코어 파운데이션과 코코아의 비대칭 성을 이해하는 것이 중요합니다. 유지, 릴리스 및 자동 릴리스는 작동하지 않습니다. 예를 들어, 릴리스 또는 자동 릴리스와 CFCreate…의 균형을 조정 한 경우 가비지 콜렉션 환경에서 오브젝트가 누출됩니다.

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

반대로, CFRelease를 사용하여 보유를 사용하여 이전에 보유한 오브젝트를 해제하면 참조 카운트 언더 플로우 오류가 발생합니다.


추신 : Peter Hosey의 답변에 대해 언급 할 수없는 것 같습니다-불필요하게 내 자신을 추가 한 것에 대해 죄송합니다.


3

타입 캐스트만으로 CFString에서 NSString으로 이동할 수있을뿐만 아니라 다른 방식으로도 작동한다고 덧붙입니다. CFStringCreateWithCString나중에 해제해야 할 메시지가 적어 메시지 를 삭제할 수 있습니다 . (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;

-3

다음을 사용할 수 있습니다. CFStringRef로 idc;

NSString *sId = [NSString stringWithFormat:@"%@", (NSString*)idc];
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.