ios阻止了潜在的内存泄漏

时间:2012-05-02 00:33:13

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

- (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中运行。我有潜在的泄漏警告,我不知道如何解决它。建议?

3 个答案:

答案 0 :(得分:8)

是的,这是内存泄漏。您打算使用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编码函数换成了结果,只是为了缩短它。

答案 1 :(得分:0)

返回字符串的自动释放版本,CFStringRef可以转换为NSString,反之亦然,这也意味着您可以像普通NSString一样对待它,从而自动释放它(如果您对此感兴趣,请阅读FoundationCore Foundation部分之间的免费桥接

答案 2 :(得分:0)

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

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

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