質問
フォームの使用後に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を使用していますか?使用している場合、どのバージョンですか?