如何将 CFStringRef 转换为 NSString?

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

我怎样才能从 aCFString得到一个新的 NSString

98924 次浏览

它们是等价的,所以你可以直接使用 CFStringRef:

NSString *aNSString = (NSString*)aCFString;

有关更多信息,请参见 免费桥型

NSString 和 CFStringRef 是“免费桥接”,这意味着您可以在它们之间进行类型转换。

例如:

CFStringRef aCFString = (CFStringRef)aNSString;

工作完美而透明。同样地:

NSString *aNSString = (NSString *)aCFString;

前面的语法是针对 MRC 的。如果您正在使用 ARC,新的强制转换语法如下:

NSString *aNSString = (__bridge NSString *)aCFString;

效果也不错。需要注意的关键是 CoreFoundation 通常返回引用计数为 + 1的对象,这意味着需要释放它们(所有 CF [ Type ] Create 格式函数都这样做)。

好的一面是,在 Cocoa 中你可以安全地使用自动释放或释放来释放它们。

我要补充的是,不仅可以使用类型强制转换从 CFString 转换为 NSString,而且还可以使用其他方式。您可以删除 CFStringCreateWithCString消息,这样稍后您就少了一个需要发布的内容。(CF 使用 Create,而 Cocoa 使用 alloc,因此无论哪种方式,您都需要发布它。)

由此产生的代码:

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

实际上,一般情况下,不应该在 Core Foundation 对象上使用 Cocoa 保留、发布和自动发布。如果您正在使用垃圾收集(目前仅在 MacOSX 上) ,那些保留、发布、自动发布调用都是禁止操作的。所以才会有内存泄漏。

来自苹果 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 来释放您以前使用 stay 保留的对象将导致引用计数底流错误。


附注: 似乎不能对彼得 · 霍西的回答作出评论——抱歉在不必要的情况下添加了我自己的回答。

我在 ARC 和 CFStrings 的保留计数方面遇到了问题。对我来说,使用 NilObjects 解决方案加上一点小小的调整非常完美。我刚刚加了保留 E。

CFStringRef cfstringRef = (__bridge_retained  CFStringRef)aNsString;

你必须投它:

CFStringRef CFstringFileName=(__bridge CFStringRef)NSstringFileName;

如果您在最近的 Mac OS X/Objective C 版本中使用 ARC, 这是 真的很简单:

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

然而,当您尝试使用免费桥梁时,Xcode 会很高兴地提醒您吗 并提供将其自动包装到 CFBridgingrelease ()中, 您可以接受并让它自动为您插入包装器,如果您单击该选项。

您可以使用: 使用 CFStringRef idc;

NSString *sId = [NSString stringWithFormat:@"%@", (NSString*)idc];