【问题标题】:How to convert CFStringRef to NSString?如何将 CFStringRef 转换为 NSString?
【发布时间】:2009-03-12 20:33:29
【问题描述】:
NSString *aNSString;
CFStringRef aCFString;
aCFString = CFStringCreateWithCString(NULL, [aNSString UTF8String], NSUTF8StringEncoding);
aCFString = CFXMLCreateStringByUnescapingEntities(NULL, aCFString, NULL);

如何从aCFString 获得新的NSString

【问题讨论】:

    标签: cocoa string cfstring


    【解决方案1】:

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

    例如:

    CFStringRef aCFString = (CFStringRef)aNSString;
    

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

    NSString *aNSString = (NSString *)aCFString;
    

    之前的语法是针对 MRC 的。如果您使用 ARC,则新的转换语法如下:

    NSString *aNSString = (__bridge NSString *)aCFString;
    

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

    好消息是,在 Cocoa 中,您可以安全地使用 autorelease 或 release 来释放它们。

    【讨论】:

    • 如果您使用的是 ARC,则这种情况下的新转换语法现在是 NSString *aNSString = (__bridge NSString *)aCFString
    • 感谢 MikeG,我不得不为反向转换做类似的事情: NSString *str=@"abc"; CFStringRef cstrref=(__bridge CFStringRef)str;
    • @NilObject 请更新您的答案以包括 ARC,这样搜索者就不必检查 cmets。谢谢。
    【解决方案2】:

    如果您在最新版本的 Mac OS X/Objective C 中使用 ARC, 这真的很容易:

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

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

    【讨论】:

    • 我不确定,但我认为(__bridge NSString *) 就足够了:用CFBridgingRelease() 增加保留计数没有意义。
    【解决方案3】:

    它们是等价的,所以你可以直接转换 CFStringRef:

    NSString *aNSString = (NSString*)aCFString;
    

    有关详细信息,请参阅Toll-Free Bridged Types

    【讨论】:

      【解决方案4】:

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

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


      PS:似乎无法评论 Peter Hosey 的回答 - 很抱歉不必要地添加了我自己的回答。

      【讨论】:

        【解决方案5】:

        我要补充一点,你不仅可以只使用类型转换从 CFString 转到 NSString,而且还可以以其他方式工作。您可以删除CFStringCreateWithCString 消息,这是您稍后需要发布的少一件事。 (CF 使用 Create,而 Cocoa 使用 alloc,所以无论哪种方式,你都需要释放它。)

        生成的代码:

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

        【讨论】:

          【解决方案6】:

          我遇到了 ARC 和 CFString 的保留计数的问题。使用 NilObjects 答案稍加调整对我来说非常完美。我刚刚添加了保留,例如。

          CFStringRef cfstringRef = (__bridge_retained  CFStringRef)aNsString;
          

          【讨论】:

            【解决方案7】:

            你必须投射它:

            CFStringRef CFstringFileName=(__bridge CFStringRef)NSstringFileName;
            

            【讨论】:

              【解决方案8】:

              你可以使用 :With CFStringRef idc;

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-08-22
                • 1970-01-01
                • 1970-01-01
                • 2013-06-18
                • 1970-01-01
                • 1970-01-01
                • 2012-02-10
                • 2013-07-24
                相关资源
                最近更新 更多