【问题标题】:How to deterministically release Core Foundation object in Garbage Collected environment?如何在垃圾收集环境中确定性地释放核心基础对象?
【发布时间】:2009-12-22 23:02:57
【问题描述】:

我在垃圾收集环境中使用 Core Foundation 方法。根据documentation 调用 CFRelease 只是减少引用计数但不释放对象:

垃圾收集环境和引用计数环境的区别在于对象释放的时间。在引用计数环境中,当对象的保留计数降至 0 时,它会立即释放;在垃圾收集环境中,当 Core Foundation 对象的保留计数从 1 变为 0 时会发生什么取决于它在内存中的位置:

  • 如果对象在 malloc 区域中,则立即解除分配。
  • 如果对象在垃圾回收区,最后一个 CFRelease() 不会立即释放该对象,它只是使其有资格在发现无法访问时被回收器回收——也就是说,一旦所有对它的强引用都消失了。因此,只要该对象仍被对象类型的实例变量(尚未标记为__weak)、寄存器、堆栈或全局变量引用,就不会被收集。

有时我会打开持有成本高昂的资源,例如网络上的文件:

CGImageSourceRef imageSource = CGImageSourceCreateWithURL(url, NULL);

是否可以在不等待垃圾收集器的情况下确定性地释放 imageSource 对象(关闭、处置、销毁、杀死混蛋)?

.Net Framework 有 IDisposable 接口,我可以这样做:

using (Font myFont = new Font("Arial", 10.0f))
{
    // use myFont
} // compiler will call Dispose on myFont

Objective-C/Cocoa 中有类似的东西吗?

【问题讨论】:

    标签: cocoa garbage-collection core-foundation


    【解决方案1】:

    using CoreFoundation with garbage collection 上查看 Apple 的文档。 TLDR 版本:分配 kCFAllocatorMallocZone 中的对象以将它们从垃圾收集系统中排除。

    【讨论】:

    • 但是怎么做呢? CGImageSourceCreateWithURL 没有 alloc 参数。
    【解决方案2】:

    首先,CFImageSources 可能没有分配到垃圾收集区。因此,您可能只需发布最后一个参考就可以了。 (大多数情况下,只有源自 Objective-C 的对象才被分配到垃圾收集区。)

    其次,如果需要,您可以简单地从 URL 下载数据并从数据中打开图像源,如果您需要保证不会打开任何内容。

    没有与 IDisposable 接口直接等效的接口,但许多类型支持手动关闭。不过,CFImageSource 不是其中之一。

    【讨论】:

      【解决方案3】:

      CFRelease 是适用于没有专用发布功能的 CoreFoundation 对象的方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-14
        • 1970-01-01
        • 1970-01-01
        • 2011-11-27
        • 1970-01-01
        • 2016-08-23
        • 2010-11-08
        相关资源
        最近更新 更多