使用CFStringRef和CFRelease进行适当的内存管理

时间:2013-02-19 19:02:50

标签: objective-c automatic-ref-counting core-foundation

考虑这个简单的方法;它是NSString上的一个类别。

- (NSString *)stringByUrlEncoding
{
    CFStringRef newString = CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", kCFStringEncodingUTF8);
    NSString *returnString = (__bridge NSString *)newString;
    CFRelease(newString);
    return returnString;
}

其工作是将=转换为%3D等进行网址编码,但这与此问题无关。

关于内存管理的一些问题:

  1. 调用CFRelease(newString);后,我仍然可以在调试器中po newString查看字符串。这是否意味着它没有得到适当的解除分配?

  2. 当我将已铸造的CFStringRefs传递给CFURLCreateStringByAddingPercentEscapes的参数时(例如(CFStringRef)self)我相信我不需要将它们存储到变量然后由于“免费”而CF发布它们桥接”。这是对的吗?

  3. 如果它是CGImageRef而不是CFStringRef,#2的答案是否会改变?为什么CGImageRef有自己的CGImageRelease函数,但是没有CFStringRelease方法?

  4. 为确保我对__bridge_transfer的理解是正确的,此修改后的代码是否相同?

    - (NSString *)stringByUrlEncoding
    {
        CFStringRef newString = CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", kCFStringEncodingUTF8);
        NSString *returnString = (__bridge_transfer NSString *)newString;
        // CFRelease(newString);
        return returnString;
    }
    

1 个答案:

答案 0 :(得分:2)

关于你的问题:

1)您没有足够的信息来了解newString是否应该已取消分配。例如,如果实际上不需要替换字符,那么CFURLCreateStringByAddingPercentEscapes返回相当于[self retain]的内容是合理的。这只是一个例子。更广泛的一点是“你无法知道”。这里的常规方法是使用Instruments来查找堆增长和泄漏。有关更多信息,谷歌“retainCount无用”(我不会在这里重复。)

2)是的。

3)CGImageRef并非免费桥接,但据我所知,CFRetainCFRelease应该有效。这里CFReleaseCGImageRelease之间的差异是CFRelease的参数不能是NULL,而CGImageRelease会容忍NULL个参数。< / p>

4)__bridge_transfer是适用于此处的注释。这将“保留计数”从ARC未处理的一侧“转移”到它所处理的一侧。换句话说,__bridge_transfer只是告诉ARC它需要为此指针创建release调用,即使它从未生成retain