6

メモリ管理されたコードで、オブジェクトが特定の所有者に属していない状況、つまりオブジェクト自体が解放された状況を処理するための推奨される方法を考えています。そのような例の 1 つは、単一のウィンドウの入力と出力を構成、表示、および管理する NSWindowController のサブクラスです。コントローラー オブジェクトはウィンドウを表示し、後である時点 (通常は、それが管理するウィンドウまたはシートが閉じられたとき) にそれ自体を解放します。AppKit にもいくつかの例が用意されています。NSAnimation は startAnimation に保持され、アニメーションが完了すると解放されます。もう 1 つの例は NSWindow で、閉じたときにそれ自体を解放するように構成できます。

これらの「自己所有」オブジェクトを自分で実装すると、少なくとも 3 つの異なる GC セーフ パターンが見られますが、それらすべてにいくつかの欠点があります。

a)。CFRetain/CFRelease を使用します。

自己所有のオブジェクトは、その操作を開始する前に自己に対して CFRetain を呼び出します (たとえば、ウィンドウ コントローラーの例では、ウィンドウが表示される前)。次に、完了したら自分自身で CFRelease() を呼び出します (たとえば、ウィンドウが閉じられた後のウィンドウ コントローラーの例)。

長所: オブジェクトのユーザーは、メモリ管理について心配する必要がありません。
短所: 純粋な ObjC コードで GC を使用していますが、メモリ管理関数を使用する必要があるため、少し見苦しいです。CFRelease() が呼び出されない場合、リークを特定するのが難しい場合があります。

b)。静的データ構造による自己所有のイディオムの回避。

オブジェクトは、操作を開始する前にデータ構造 (静的可変配列など) に自身を追加し、操作が完了するとそこから削除します。

長所: オブジェクトのユーザーは、メモリ管理について心配する必要がありません。メモリ管理関数の呼び出しはありません。オブジェクトには明示的な所有者がいます。潜在的な漏れは簡単に特定できます。
短所: オブジェクトが異なるスレッドから作成される可能性がある場合は、ロックが必要です。余分なデータ構造。

c)。オブジェクトのユーザーにオブジェクトへの参照を保存することを要求することにより、自己所有のイディオムを回避します (ivar など)。

長所: メモリ管理関数を呼び出さない。オブジェクトには明示的な所有者がいます。
短所: オブジェクトのユーザーは、オブジェクトが不要になった場合でも参照を保持する必要があります。エクストラ・イヴァル。

これらのケースを処理するには、どのパターンを使用しますか?

4

2 に答える 2

5

a) の場合、 /のより慣用的な代替手段はCFRetain(foo)/です。CFRelease(foo)[[NSGarbageCollector defaultCollector] disableCollectorForPointer:foo][[NSGarbageCollector defaultCollector] enableCollectorForPointer:foo]

于 2008-10-28T18:06:32.707 に答える
2

Appleの推奨は(c)ですが、私は(b)の音が好きです。静的データ構造により、CFRetain/CFRelease レベルに陥ることを回避しながら、API ユーザーから GC の詳細を隠すことができます。あなたが述べているように、デバッグと単体テストも容易になります。オブジェクトがタスクを完了した後も静的データ構造によって参照されている場合は、バグがあることがわかります。

于 2008-10-28T12:50:22.687 に答える