参照カウントの使用

提供: RAD Studio
移動先: 案内検索

インターフェイス オブジェクトのメモリ管理 への移動


メモ: このトピックでは、すべての Delphi コンパイラでサポートされている、インターフェイスの参照カウントについて説明します。Delphi モバイル コンパイラでは、さらに、クラスの自動参照カウントもサポートしています。詳細については、「Delphi モバイル コンパイラでの自動参照カウント」を参照してください。

Delphi コンパイラでは、インターフェイスの問い合わせと参照カウントの実装により、IInterface のメモリ管理機能のほとんどを提供しています。したがって、インターフェイスにより生成および破棄されるオブジェクトがある場合は、TInterfacedObject から派生させることによって参照カウントを簡単に使用できます。参照カウントを使用することにした場合は、オブジェクトをインターフェイス参照としてのみ保持し、一貫した参照カウントを行うことに注意しなければなりません。次に例を示します。

procedure beep(x: ITest);
function test_func()
var
  y: ITest;
begin
  y := TTest.Create; // because y is of type ITest, the reference count is one
  beep(y); // the act of calling the beep function increments the reference count
  // and then decrements it when it returns
  y.something; // object is still here with a reference count of one
end;

これは、最も簡潔で安全なメモリ管理アプローチで、TInterfacedObject を使用する場合は、自動的に処理されます。このルールに従わない場合、次のコードに示すように、オブジェクトが予期せず消滅してしまうおそれがあります。

function test_func()
var
  x: TTest;
begin
  x := TTest.Create; // no count on the object yet
  beep(x as ITest); // count is incremented by the act of calling beep
  // and decremented when it returns
  x.something; // surprise, the object is gone
end;

メモ: 上記の例で、beep 手続きは、宣言のとおりに、パラメータの参照カウントをインクリメントさせます(_AddRef の呼び出し)。これに対して、次の宣言の場合はどちらもそうではありません。

procedure beep(const x: ITest);

または

procedure beep(var x: ITest);

これらの宣言の場合、生成されるコードはより小さく高速です。

一貫した適用ができないために参照カウントを使用できないケースの 1 つは、オブジェクトが、別のコンポーネントに所有されているコンポーネントやコントロールである場合です。この場合でもインターフェイスを使用することはできますが、オブジェクトの存続時間がそのインターフェイスで決定されるわけではないので、参照カウントを使用してはなりません

関連項目