objective-c - ARC 和 CFRelease?

标签 objective-c ios cocoa-touch 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;
}

注释掉的三个 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;
}

关于objective-c - ARC 和 CFRelease?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14064336/

相关文章:

objective-c - 将不可变对象(immutable对象)转换为可变对象(递归)的最佳方法是什么?

ios - 在顶部 uiview 下方捕获 uiview 的图像

objective-c - 带有小数点分隔符的 NSString 到 NSNumber

ipad - 我们如何打印包含 uiimage 的 ipad View 和多行的 uitableview

ios - 将 Quartz 方法从 iOS 转换为 OSX

ios - 用于IOS标记的Google Maps SDK已被覆盖

ios - 在 block 中将 self 作为参数不会导致循环引用,但对 self 的外部引用会导致循环引用

mysql - 我正在制作一个 IOS 应用程序,如何让该应用程序向我发送其所在设备的 UDID?

ios - UIAttachmentBehavior 中的长度是如何确定的?

objective-c - 在 textFieldShouldReturn 之后调用方法