2009-05-27 9 views
9

Delphiのオンラインヘルプによれば、メモリからフォームを削除するにはリリースを使用する必要があります。しかし、モーダルフォームの多くの例では、私はこの構造を見てきました:Delphiのモーダルフォームにリリースの代わりにフリーを使用するのは安全ですか?

MyForm := TMyForm.Create(nil); 
try 
    MyForm.ShowModal; 
finally 
    MyForm.Free; 
end; 

モーダルフォームを安全に破壊する方法はありますか? ShowModalのソースで見ることができるように、Application.HandleMessageはModalResultが0になるまで呼び出されます。これが、Freeが保留中のWindowsメッセージを妨害できない理由ですか?

+0

関連:http://stackoverflow.com/questions/274523/form-release-nil – mjn

答えて

14

ShowModalの呼び出し後に、Freeを使用しても安全です。

Releaseを使用する必要がある場合は、イベントハンドラ(たとえば、OnClick)の途中で、イベント後の処理がフォームにアクセスする必要がある場合があります。この場合、代わりにReleaseを呼び出すと、イベントハンドラが完了して制御がメッセージポンプ(ProcessMessages/Application.Run)に返されるまで、イベントを解放しないメッセージCM_RELEASEがポストされます。 ShowModalは、イベントハンドラが終了して制御によってスタックがバックアップされるまで返されないので、Freeを後で呼び出すと、実際にはCM_RELEASEメッセージが処理される同じ場所になります。

+0

そして、Application.ProcessMessagesの呼び出しをしないように注意してください! –

+0

@GerryCollなぜですか?正確にはどこですか? – Bozzy

+0

@Bozzy 'Release'を使い、' Application.ProcessMessages'を呼び出すと、 'WM_RELEASE'メッセージが処理され、フォームが解放されます。 Gerryの懸念は、リリースを使用して破壊を延期した後、フォームを実際に完了する前に誤ってフォームを解放している場合です。 –

3

もちろん、FreeAndNilルーチンを使用することもできます。 FreeAndNilルーチンは、オブジェクトがまだnilでない場合にのみ解放し、解放後もnilに設定します。すでに解放されているオブジェクトに対して無料で直接呼び出すと、アクセス違反が発生します。

MyForm := TMyForm.Create(nil); 
try 
    MyForm.ShowModal; 
finally 
    FreeAndNil(MyForm); 
end; 
+4

小さなニックピック:無料でもオブジェクトが解放されていない場合は、2番目の部分が重要です。 – mghie

+3

MyFormがローカル変数の場合、FreeAndNil()を使用することは確かに過剰です。 MyForm.Freeで十分です。実際はMyForm.Destroyも同様に動作します。 –

+1

+ for Allen - FreeAndNilを過度に使用すると、コンパイラによって選択されたエラーを隠すことができます。オブジェクトが初期化されていない場合(通常は条件付き作成)、エラーは発生しません。 これは質問にも答えません(そうです)。 –

4

によって異なります。 Freeフォームでは、Releaseのイベントハンドラは呼び出されず、フォームに投稿され、キューに入れられたメッセージは処理されません。したがって、多くの場合、おそらくほとんどのケースでFree(またはFreeAndNil)が正常に動作しますが、それは一見ランダムな理由から非常に奇妙な動作につながる可能性があります。

procedure FormClose(Sender : TObject; Action : TCloseAction) 
begin 
    Action := caFree; 
end; 

あなたは、このようなコードを書くことができます:

TMyForm.Create(nil).ShowModal; 

そして、あなたドン

私がお勧めしたいの代替がOnCloseのイベントであるが、このように、caFreeにアクションを設定しますそれが完了したらそれ自身を解放するので、具体的にフォームを解放する必要はありません。

+0

私はこれが示す創造性が好きですが、質問に表示されるコードはそれを行うための慣用的な方法なので、決して使用しません。コードを使って、数ヶ月後にフォームが正しく解放されるかどうか、 。 – mghie

+0

あなたは気持ちが最高です。しかし、これはフォームの機能を完全にカプセル化し、解放することを忘れる可能性を減らします。 –

+0

caFreeにアクションを設定すると、単にReleaseが呼び出されます。何か(壊れた?)がProcessMessagesを呼び出す場合に、showmodalの後にフォームのプロパティにアクセスしたい場合は注意が必要です。 –

関連する問題