【问题标题】:Self-owned objects in Objective-C Garbage CollectionObjective-C 垃圾回收中的自有对象
【发布时间】:2010-09-19 13:48:05
【问题描述】:

我想知道在内存管理的代码中,处理对象不属于任何特定所有者(即对象自己释放)的情况的推荐方法是什么。一个这样的例子可能是 NSWindowController 的子类,它配置、显示和管理单个窗口的输入和输出。控制器对象显示一个窗口并稍后在某个时候释放自己(通常在它管理的窗口或工作表关闭时)。 AppKit 也提供了几个例子: NSAnimation 在 startAnimation 中保留自己,并在动画完成时释放自己。另一个例子是 NSWindow,它可以被配置为在关闭时释放自己。

在自己实现这些“自有”对象时,我看到至少三种不同的 GC 安全模式,但它们都有一些缺点。

一)。使用 CFRetain/CFRelease。

自有对象在开始操作之前调用自身的 CFRetain(例如,在显示窗口之前的窗口控制器示例中)。然后它在完成后调用自身的 CFRelease()(例如,在窗口关闭后的窗口控制器示例中)。

优点:对象的用户不必担心内存管理。
缺点:有点难看,因为需要使用内存管理功能,尽管我们在纯 ObjC 代码中使用 GC。如果没有调用 CFRelease(),泄漏可能很难定位。

b)。避免使用静态数据结构的自我所有权习语。

对象在开始操作之前将自己添加到数据结构(例如静态可变数组)中,并在完成后将自己从那里移除。

优点:对象的用户不必担心内存管理。不调用内存管理函数。对象有明确的所有者。潜在的泄漏很容易找到。
缺点:如果可以从不同的线程创建对象,则需要锁定。额外的数据结构。

c)。通过要求对象的用户保存对对象的引用(例如保存到 ivar)来避免自我所有权习惯用法。

优点:无需调用内存管理函数。对象有明确的所有者。
缺点:对象的用户必须保留一个引用,即使它不再需要该对象。额外的 ivars。

你会用什么模式来处理这些情况?

【问题讨论】:

    标签: objective-c cocoa garbage-collection


    【解决方案1】:

    对于 a),CFRetain(foo)/CFRelease(foo) 的更习惯用法是 [[NSGarbageCollector defaultCollector] disableCollectorForPointer:foo]/[[NSGarbageCollector defaultCollector] enableCollectorForPointer:foo]

    【讨论】:

      【解决方案2】:

      Apple 的推荐是 (c),但我喜欢 (b) 的声音。静态数据结构允许您向 API 用户隐藏 GC 详细信息,同时避免陷入 CFRetain/CFRelease 级别。正如您所说,它还使调试和单元测试更容易;如果一个对象在完成其任务后仍然被静态数据结构引用,那么你就知道有一个错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-29
        • 1970-01-01
        • 1970-01-01
        • 2011-11-29
        • 2021-12-20
        • 1970-01-01
        • 1970-01-01
        • 2011-12-14
        相关资源
        最近更新 更多