如何将CFStringRef转换为NSString?
NSString *aNSString; CFStringRef aCFString; aCFString = CFStringCreateWithCString(NULL, [aNSString UTF8String], NSUTF8StringEncoding); aCFString = CFXMLCreateStringByUnescapingEntities(NULL, aCFString, NULL);
我怎样才能从一个aCFString
获得一个新的NSString
?
NSString和CFStringRef是“免费桥接”,这意味着你可以简单地在它们之间进行types转换。
例如:
CFStringRef aCFString = (CFStringRef)aNSString;
完美透明地工作。 同样:
NSString *aNSString = (NSString *)aCFString;
以前的语法是MRC。 如果您使用的是ARC,则新的转换语法如下所示:
NSString *aNSString = (__bridge NSString *)aCFString;
也适用。 关键要注意的是,CoreFoundation通常会返回带有+1引用计数的对象,这意味着它们需要被释放(所有的CF [types]创build格式函数都这样做)。
好的是,在cocoa你可以安全地使用autorelease或释放来释放它们。
如果您在最新版本的Mac OS X / Objective C中使用ARC,那真的很简单:
NSString *happyString = (NSString *)CFBridgingRelease(sadString);
然而,当你尝试免费桥CFString到NSString,并提供自动将它包装在CFBridgingRelease(),您可以接受,并让它自动插入包装,如果你点击选项Xcode会高兴地警告你。
它们是等价的,所以你可以只投射CFStringRef:
NSString *aNSString = (NSString*)aCFString;
有关更多信息,请参阅免费桥接types 。
实际上,你不应该在Core Foundation对象上使用Cocoa retain,release,autorelease。 如果您正在使用垃圾收集(现在只在Mac OS X上),那么保留,释放,自动释放呼叫都是空操作。 因此内存泄漏。
了解Core Foundation和Cocoa之间的不对称是非常重要的,在这种情况下,保留,释放和自动释放是没有用的。 例如,如果您已经用释放或自动释放平衡了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,只需要一个types转换,但它也可以用另一种方式。 您可以删除CFStringCreateWithCString
消息,这是您稍后需要发布的less一件事情。 (CF使用Cocoa使用alloc
Create
,所以不pipe怎样,你都需要释放它。)
由此产生的代码:
NSString *escapedString; NSString *unescapedString = [(NSString *) CFXMLCreateStringByUnescapingEntities(NULL, (CFStringRef) escapedString, NULL) autorelease];
我遇到了ARC和CFStrings的保留数问题。 使用NilObjects答案稍微调整对我来说是完美的。 我只是加了保留,例如。
CFStringRef cfstringRef = (__bridge_retained CFStringRef)aNsString;
你必须投它:
CFStringRef CFstringFileName=(__bridge CFStringRef)NSstringFileName;
你可以使用:With CFStringRef idc;
NSString *sId = [NSString stringWithFormat:@"%@", (NSString*)idc];