11

フォームを使用した後に Form.Release が呼び出されると、関連するすべてのメモリが解放されますが、フォーム変数は nil に設定されません。

if not assigned (Form1) then
  begin
    Application.CreateForm(Tform1, Form1);
    try
      // Do something
    finally
      Form1.Release
    end;
  end;

同じコードを再度呼び出せるようにするには、Form1 をある時点で nil に設定する必要があります。Release の説明より

Form1 := nil;

Release の直後。これは、Release プロシージャが呼び出された直後、フォームが実際に解放される前に戻るためです。Form.Release が終了してフォーム var が nil に設定されるタイミングを検出できません。

これを行う最善の方法は何ですか?

4

5 に答える 5

17

ラインを入れる

  Form1 := nil;  

Release への呼び出しの直後。

Release は、CM_RELEASE メッセージを Form にポストするだけです。これにより、Form は CM_RELEASE メッセージを処理する前にキュー (イベント ハンドラ) にあるものを終了できます。つまり、通常は Free を呼び出すだけです。
したがって、Release を呼び出した後、Form 変数がまだ有効な Form を指していると仮定して、変数に nil を入れてはいけません。

于 2008-11-08T09:12:50.450 に答える
11

Release は、(潜在的に) 延期された Free です。Release を呼び出した後に最初にすべきことは、変数を nill することです。
そうすれば、一部のコードが実際に破棄される前に Form1 を参照しようとしても安全です。あなたのコードのような場合、新しい使用のために別の Form1 を安全に再作成するだけで、破棄されたものを気にする必要はありません。

于 2008-11-08T09:22:22.427 に答える
4

あなたはいつもこれを呼び出すことができます:

procedure FreeOrReleaseAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  if Temp is TCustomForm then
    TCustomForm(Temp).Release
  else
    Temp.Free;
end;

Obj の型はテストできないため、TObject にキャストした後は必ず型を確認してください。Free と同様に、Release は非仮想であるため、これは安全なはずです。

于 2008-11-08T19:58:43.563 に答える
2

前述のように、Release は、フォーム自体をクローズ/解放したい場合に使用するための延期された Free にすぎません。それ以外の場合は、リリースと何ら違いはありません。したがって、その例で Release を呼び出しても意味がありません。Free を呼び出す方がより論理的であるように思われます。また、Free を呼び出した後に nil に設定するか、FreeAndNil を使用できます。

Release を引き続き使用する場合は、それで問題ありません。変数値を nil に設定するだけで機能します。そうしても、フォーラムの動作が変わるわけではありません。ただし、この場合は、Release ではなく Free を呼び出す方が効率的で決定論的であることを覚えておいてください。私の好みは、本当に必要な場所でのみ Release を使用することです。

于 2008-11-08T13:47:24.453 に答える
0

Delphi Win32 では、オブジェクトを解放する適切な方法は、

FreeAndNil(Form1)

これにより、1 回の呼び出しで両方のジョブが実行されます。

しかし、あなたの質問には目に見える以上のものがあるとこっそり感じています。Delphi for .NET を使用していますか? また、使用している場合は、どのバージョンですか?

于 2008-11-08T08:53:05.497 に答える