我想知道在内存管理代码中,对象不属于任何特定所有者的情况下,推荐的方法是什么,即对象本身被释放。一个这样的例子可以是NSWindowController的子类,它配置、显示和管理单个窗口的输入和输出。控制器对象显示一个窗口,并在稍后释放自身(通常在关闭它管理的窗口或工作表时)。AppKit也提供了几个例子: NSAnimation将自己保留在startAnimation中,并在动画完成时释放自己。另一个例子是NSWindow,它可以配置为在关闭时释放自身。
当我自己实现这些“自有”对象时,我看到了至少三种不同的GC安全模式,但它们都有一些缺点。
a)。使用CFRetain/CFRelease。
自有对象在开始操作之前调用self上的CFRetain (例如,在窗口控制器示例中,在窗口显示之前)。然后,它在完成时调用self上的CFRelease() (例如,在窗口控制器示例中,在窗口关闭后)。
优点:对象的用户不必担心内存管理。
缺点:有点难看,因为需要使用内存管理函数,尽管我们在纯ObjC代码中使用GC。如果不调用CFRelease(),泄漏可能很难定位。
b)。避免使用静态数据结构的自拥有习惯用法。
对象在开始操作之前将其自身添加到数据结构(例如,静态可变数组)中,并在完成操作后从数据结构中移除自身。
优点:对象的用户不必担心内存管理。不调用内存管理函数。对象具有显式所有者。潜在的泄漏很容易定位。
缺点:如果对象可能是从不同的线程创建的,则需要锁定。额外的数据结构。
c)。通过要求object的用户保存对object的引用(例如,保存到ivar中)来避免自拥有习惯用法。
优点:不需要调用内存管理函数。对象具有显式所有者。
缺点:对象的用户必须保留一个引用,即使它不再需要该对象。额外的依瓦尔。
您将使用什么模式来处理这些情况?
发布于 2008-10-28 12:50:23
苹果的建议是(c),但我喜欢(b)的声音。静态数据结构允许您对API用户隐藏GC详细信息,同时避免涉及CFRetain/CFRelease级别。正如您所说的,它还使调试和单元测试变得更容易;如果一个对象在完成其任务后仍然被静态数据结构引用,您就知道有一个bug。
发布于 2008-10-28 18:06:33
首先,CFRetain(foo)/CFRelease(foo)更常用的替代方法是[[NSGarbageCollector defaultCollector] disableCollectorForPointer:foo]/[[NSGarbageCollector defaultCollector] enableCollectorForPointer:foo]。
https://stackoverflow.com/questions/243074
复制相似问题