質問

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

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

同じコードを再度呼び出すには、ある時点でForm1をnilに設定する必要があります。リリースの説明からできないこと

Form1 := nil;

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

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

役に立ちましたか?

解決

行を入れる

  Form1 := nil;  

Releaseの呼び出し直後。

ReleaseはCM_RELEASEメッセージをフォームにポストするだけで、CM_RELEASEメッセージを処理する前にフォームがそのキュー(イベントハンドラー)を終了できるようにします。これは通常、Freeを呼び出すだけです。
そのため、Releaseを呼び出した後、Form変数がまだ有効なFormを指していると想定してはならず、nilを変数に入れます。

他のヒント

リリースは、(潜在的に)延期された無料です。 Releaseを呼び出した後に最初にすべきことは、変数を空にすることです。
そうすれば、実際に破棄される前に一部のコードがForm1を参照しようとしても安全です。あなたのコードのようなケースでは、破壊されるものを気にすることなく、新しい使用法のために別のForm1を安全に再作成します。

常にこれを呼び出すことができます:

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は非仮想であるため、この は安全です。

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

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

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

を呼び出すことです
FreeAndNil(Form1)

これは、1回の呼び出しで両方のジョブを実行します。

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top