如何将CFStringRef转换为NSString?


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

我如何获得新NSStringaCFString

Answers:


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);

但是,当您尝试免费桥接CFString到NSString并提供将其自动包装在CFBridgingRelease()中时,Xcode会很高兴地警告您,如果您单击该选项,它可以接受并让它自动为您插入包装器。


3
我不确定,但是我认为(__bridge NSString *)足够了:用来增加保留计数是没有意义的CFBridgingRelease()
2015年


4

实际上,您一般不应在Core Foundation对象上使用Cocoa保留,释放,自动释放。如果您使用的是垃圾回收(目前仅在Mac OS X上使用),则这些保留,释放,自动释放的调用都是无操作的。因此内存泄漏。

从Apple 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消息,这是以后需要发布的少一件事。(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

您可以使用:With CFStringRef idc;

NSString *sId = [NSString stringWithFormat:@"%@", (NSString*)idc];
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.