考虑这个简单的方法;它是NSString上的一个类别。
- (NSString *)stringByUrlEncoding
{
CFStringRef newString = CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", kCFStringEncodingUTF8);
NSString *returnString = (__bridge NSString *)newString;
CFRelease(newString);
return returnString;
}
其工作是将=
转换为%3D
等进行网址编码,但这与此问题无关。
关于内存管理的一些问题:
调用CFRelease(newString);
后,我仍然可以在调试器中po newString
查看字符串。这是否意味着它没有得到适当的解除分配?
当我将已铸造的CFStringRefs传递给CFURLCreateStringByAddingPercentEscapes的参数时(例如(CFStringRef)self
)我相信我不需要将它们存储到变量然后由于“免费”而CF发布它们桥接”。这是对的吗?
如果它是CGImageRef而不是CFStringRef,#2的答案是否会改变?为什么CGImageRef有自己的CGImageRelease函数,但是没有CFStringRelease方法?
为确保我对__bridge_transfer
的理解是正确的,此修改后的代码是否相同?
- (NSString *)stringByUrlEncoding
{
CFStringRef newString = CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", kCFStringEncodingUTF8);
NSString *returnString = (__bridge_transfer NSString *)newString;
// CFRelease(newString);
return returnString;
}
答案 0 :(得分:2)
关于你的问题:
1)您没有足够的信息来了解newString
是否应该已取消分配。例如,如果实际上不需要替换字符,那么CFURLCreateStringByAddingPercentEscapes
返回相当于[self retain]
的内容是合理的。这只是一个例子。更广泛的一点是“你无法知道”。这里的常规方法是使用Instruments来查找堆增长和泄漏。有关更多信息,谷歌“retainCount无用”(我不会在这里重复。)
2)是的。
3)CGImageRef
并非免费桥接,但据我所知,CFRetain
和CFRelease
应该有效。这里CFRelease
和CGImageRelease
之间的差异是CFRelease
的参数不能是NULL
,而CGImageRelease
会容忍NULL
个参数。< / p>
4)__bridge_transfer
是适用于此处的注释。这将“保留计数”从ARC未处理的一侧“转移”到它所处理的一侧。换句话说,__bridge_transfer
只是告诉ARC它需要为此指针创建release
调用,即使它从未生成retain
。