mjn*_*mjn 13 forms delphi memory-management modal-dialog
Delphi在线帮助说,Release应该用于从内存中删除表单.但是,在模态形式的许多例子中,我看到了这个结构:
MyForm := TMyForm.Create(nil);
try
MyForm.ShowModal;
finally
MyForm.Free;
end;
Run Code Online (Sandbox Code Playgroud)
免费是一种破坏模态形式的安全方式吗?正如我在ShowModal的源代码中看到的那样,将调用Application.HandleMessage,直到ModalResult不为0.这就是为什么Free不能干扰挂起的Windows消息的原因?
Zoë*_*son 17
是的,通话Free
后可以安全使用ShowModal
.
您需要使用的情况Release
是当您处于事件处理程序(例如OnClick
)的中间时,事件之后的进一步处理将必须访问该表单.在这种情况下,调用Release
会发布一条CM_RELEASE
消息,该消息不会释放事件,直到事件处理程序完成并且控制已返回到消息泵(ProcessMessages
/ Application.Run
). ShowModal
在事件处理程序完成并且控制使其备份到堆栈之前不会返回,因此Free
之后的调用实际上与CM_RELEASE
处理消息的位置相同.
这取决于.Free
表单不会调用事件处理程序,Release
并且不会处理可能已发布到表单并排队的任何消息.因此,虽然在很多情况下Free
(或者说大多数情况下)调用(或FreeAndNil
)可以正常工作,但由于看似随机的原因,可能会导致一些非常奇怪的行为.
我建议的替代方案是在OnClose事件中将Action设置为caFree,如下所示:
procedure FormClose(Sender : TObject; Action : TCloseAction)
begin
Action := caFree;
end;
Run Code Online (Sandbox Code Playgroud)
然后你可以编写如下代码:
TMyForm.Create(nil).ShowModal;
Run Code Online (Sandbox Code Playgroud)
而且你不需要特别释放表单,因为它会在完成后自由释放.
绝对可以,您也可以使用 FreeAndNil 例程。FreeAndNil 例程只会在对象尚未为 nil 时才释放该对象,并在释放后将其设置为 nil。如果你直接在一个已经被释放的对象上调用 free,你会得到一个访问冲突。
MyForm := TMyForm.Create(nil);
try
MyForm.ShowModal;
finally
FreeAndNil(MyForm);
end;
Run Code Online (Sandbox Code Playgroud)