PaR*_*Nos 33 cocoa-touch objective-c ios automatic-ref-counting
我有点困惑.我读过的每个地方都建议,在使用ARC时,你仍然需要释放有意义的核心基础对象,ARC不管理它们.但是,我有一个方法,它使用我使用的一些CF方法/对象CFRelease,但然后导致应用程序崩溃.取消注释我CFRelease的问题解决了这个问题,但后来我假设我有内存泄漏?
有人可以解释哪些东西需要发布,哪些不需要,或者其他任何错误的代码?
+ (NSString *) fileExtensionForMimeType:(NSString *)type
{
CFStringRef mimeType = (__bridge CFStringRef)type;
CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType, NULL);
CFStringRef extension = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension);
NSString *ext = (__bridge NSString *)extension;
// CFRelease(mimeType);
// CFRelease(uti);
// CFRelease(extension);
return ext;
}
Run Code Online (Sandbox Code Playgroud)
三个注释掉的CFRelease电话修复了上述问题,但我知道这是错误的.我该怎么办?
rma*_*ddy 38
您无法发布,mimeType因为您不拥有它.您没有使用__bridge演员转让所有权.
你应该发布,uti因为你已经创建它.
您也应该extension在创建它之后发布,但这可能会导致问题ext.相反,将所有权转移到ext.
我建议如下:
+ (NSString *) fileExtensionForMimeType:(NSString *)type {
CFStringRef mimeType = (__bridge CFStringRef)type;
CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType, NULL);
CFStringRef extension = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension);
NSString *ext = (__bridge_transfer NSString *)extension;
// CFRelease(mimeType); // not owned
if (uti) CFRelease(uti);
// CFRelease(extension); // ownership was transferred
return ext;
}
Run Code Online (Sandbox Code Playgroud)
Rob*_*Rob 15
查看WWDC 2012 - 现代Objective-C,其中概述了Core Foundation对象和ARC的新指南.该视频大概是37:35.简而言之,Core Foundation 在名称Copy或Create名称中的功能创建了一个将所有权转移到您的应用程序的对象,您的应用程序负责释放它.
无论如何,如果所有权已通过Core Foundation方法使用Copy或Create以名称传输,您可以在完成后手动释放CFRelease它,或者更容易,您可以将所有权转移到ARC并让它来处理它.从历史上看,为了将所有权转让给ARC,我们使用了__bridge_transfer,但他们现在推荐CFBridgingRelease(尽管后者只是前者的宏).而且,显然,如果您有一些Core Foundation对象,您通过其他机制检索除了名称Copy或函数之外的其他机制Create,您既不CFRelease应该也不应该将所有权转移给ARC.
举例来说,这种方法可以实现你想要的:
+ (NSString *) fileExtensionForMimeType:(NSString *)type {
NSString *uti = CFBridgingRelease(UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType,
(__bridge CFStringRef)type,
NULL));
return CFBridgingRelease(UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)uti,
kUTTagClassFilenameExtension));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11424 次 |
| 最近记录: |