【问题标题】:ios thwarting a potential memory leakios 阻止潜在的内存泄漏
【发布时间】:2012-05-02 00:33:12
【问题描述】:
- (NSString*)encodeURL:(NSString *)string
{
    NSString *newString = (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, CFSTR(":/?#[]@!$ &'()*+,;=\"<>%{}|\\^~`"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));

    if (newString) 
    {
        return newString; // <-- potential leak here
    }

    return @"";
}

我不熟悉 CFTypes(除了知道它们是什么)。这是我从互联网上获得的代码,我不得不费力地让它在 ARC 中工作。我收到了潜在的泄漏警告,但不知道如何解决。有什么建议吗?

【问题讨论】:

    标签: ios memory-management automatic-ref-counting cftypes


    【解决方案1】:

    是的,这是内存泄漏。你的意思是使用CFBridgingRelease() 而不是__bridge

    CFURLCreateStringByAddingPercentEscapes 创建的对象有一个额外的保留,因为它包含Create。您需要将该对象传输到 ARC,让它知道添加一个额外的版本,这就是 CFBridgingRelease() 所做的。

    NSString *newString = 
        CFBridgingRelease(
            CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, 
                                                   (__bridge CFStringRef)string, 
                                                   NULL,
                                                   CFSTR(":/?#[]@!$ &'()*+,;=\"<>%{}|\\^~`"),           
                                                   kCFStringEncodingUTF8));
    

    您确实使用__bridge 作为传入的字符串,因为您没有将其传输到Core Foundation。您只是要求 Core Foundation 使用它,而 ARC 继续拥有它。当您“转让”所有权时,您通常的意思是“这个对象曾经是 Core Foundation,现在是 ARC”(反之亦然)。这就是 newString 发生的事情。

    我用结果替换了长的 NS-to-CF 编码函数,只是为了让它更短。

    【讨论】:

      【解决方案2】:

      返回字符串的自动释放版本,CFStringRef 可以转换为NSString,反之亦然,这也意味着您可以将其视为普通的NSString,从而自动释放它(如果您对此感兴趣您应该阅读有关FoundationCore Foundation 部分之间的免费桥接的信息)

      【讨论】:

      • 这是 ARC 代码(因为它使用 __bridge)。您不能在 ARC 代码中手动自动释放。
      • @RobNapier Argh,你们这些孩子,还有你们新的闪亮的东西^^对不起,完全错过了那部分。
      【解决方案3】:

      另一种方法是使用 __bridge_transfer 代替 __bridge,如下所示:

      NSString *newString = (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, CFSTR(":/?#[]@!$ &'()*+,;=\"<>%{}|\\^~`"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
      

      在这个问题中查看更多信息:Correct bridging for ARC?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-06
        • 2011-10-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多