我稍微困惑。 我到处都读过,建议使用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;
}
三个注释掉CFRelease
电话解决所提及的问题,但我知道这是错的。 我应该怎么做?
你不能释放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;
}
看看WWDC 2012 -现代的Objective-C ,其概述了核心基础对象和ARC的新准则。 这是关于37:35到该视频。 在短,Core Foundation的功能Copy
或Create
的名称创建已转移所有权转让给你的应用的对象,您的应用程序负责释放它。
无论如何,如果所有权已经通过Core Foundation的方法转移与Copy
或Create
的名称,您可以手动释放CFRelease
当你用它做,或者更简单,你可以将所有权转让给ARC让它来呵护它。 从历史上看,将所有权转让给ARC,我们使用__bridge_transfer
,但他们现在建议CFBridgingRelease
(尽管后者只是前者的宏)。 而且,很明显,如果您有通过比使用其他功能其他机制检索到的一些核心基础对象Copy
或Create
的名称,你应该既不CFRelease
,也没有将所有权转让给ARC。
通过图示的方式,这种方法实现你想要什么:
+ (NSString *) fileExtensionForMimeType:(NSString *)type {
NSString *uti = CFBridgingRelease(UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType,
(__bridge CFStringRef)type,
NULL));
return CFBridgingRelease(UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)uti,
kUTTagClassFilenameExtension));
}
在通常来说,我想你应该试评第一CFRelease(媒体类型)的线,并取消注释随后两行:CFRelease(UTI)和CFRelease(扩展)。 你投一个免费的桥梁,输入的NSString和ARC将手柄上的释放。 但UTI和延伸创建/复制为CFString字符串。 ARC将不知道如何处理它们(记住ARC是NSObject的编译器功能),所以你需要CF释放他们。