在 Delphi 中使用Free而不是Release作为模态表单安全吗?

liwlm1x9  于 9个月前  发布在  其他
关注(0)|答案(3)|浏览(119)

Delphi 在线帮助中说Release应该用来从内存中删除表单。然而,在许多模态表单的例子中,我看到了这个结构:

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

字符串
Free是否是销毁模态表单的安全方法?正如我在ShowModal的源代码中所看到的,Application.HandleMessage将被调用,直到ModalResult不为0。这是Free无法干预挂起的Windows消息的原因吗?

0qx6xfy6

0qx6xfy61#

是的,在ShowModal调用后使用Free是安全的。
需要使用Release的情况是当您正在处理事件处理程序时(例如,OnClick),在事件之后的进一步处理将必须访问表单。在这种情况下,而调用Release则会发布一条CM_RELEASE消息,该消息不会释放事件,直到事件处理程序完成并且控制返回到消息泵(ProcessMessages/Application.Run). ShowModal不会返回,直到事件处理程序完成并且控制使其备份堆栈,因此之后调用Free实际上是处理CM_RELEASE消息的相同位置。

m0rkklqb

m0rkklqb2#

Free调用表单不会像Release那样调用事件处理程序,任何可能已经发布到表单并排队的消息都不会被处理。因此,虽然在许多情况下,也可能是大多数情况下,调用Free(或FreeAndNil)可以正常工作,但它可能会导致一些看似随机的非常奇怪的行为。
我建议的替代方案是在OnClose事件中将Action设置为caFree,如下所示:

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

字符串
你可以这样写代码:

TMyForm.Create(nil).ShowModal;


您不需要特别释放表单,因为它会在完成后释放自己。

2skhul33

2skhul333#

当然可以,你也可以使用FreeAndNil例程。FreeAndNil例程只会在对象还不是nil的情况下释放对象,并且在释放之后将其设置为nil。如果你直接在一个已经被释放的对象上调用free,你会得到一个访问冲突。

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

字符串

相关问题