13

Delphi 在线帮助说 Release 应该用于从内存中删除表单。但是,在模态形式的许多示例中,我已经看到了这种结构:

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

Free 是破坏模态表单的安全方法吗?正如我在 ShowModal 的源代码中看到的那样,Application.HandleMessage 将被调用,直到 ModalResult 不为 0。这就是 Free 不能干扰挂起的 windows 消息的原因吗?

4

3 回答 3

18

是的,通话Free后使用是安全的ShowModal

您需要使用的情况Release是当您处于事件处理程序(例如,OnClick)中间时,事件之后的进一步处理将不得不访问表单。在这种情况下,调用Release会发布一条消息,该消息在事件处理程序完成并且控制返回到消息泵 ( / )CM_RELEASE之前不会释放事件。 在事件处理程序完成并且控制使其备份堆栈之前不会返回,因此之后调用实际上是处理消息的相同位置。ProcessMessagesApplication.RunShowModalFreeCM_RELEASE

于 2009-05-27T18:06:22.513 回答
7

这取决于。Free表单不会调用事件处理程序Release,并且任何可能已发布到表单并排队的消息都不会被处理。因此,虽然在许多甚至大多数情况下调用Free(or FreeAndNil) 都可以正常工作,但由于看似随机的原因,它可能会导致一些非常奇怪的行为。

我建议的替代方法是在 OnClose 事件中将 Action 设置为 caFree,如下所示:

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

然后,您可以编写如下代码:

TMyForm.Create(nil).ShowModal;

而且您不需要专门释放表单,因为它会在完成后自行释放。

于 2009-05-27T17:27:07.910 回答
5

当然,您也可以使用 FreeAndNil 例程。FreeAndNil 例程将仅在对象尚未为 nil 时释放该对象,并在释放后将其设置为 nil。如果你直接在一个已经被释放的对象上调用 free,你会得到一个访问冲突。

MyForm := TMyForm.Create(nil); 
try 
  MyForm.ShowModal; 
finally 
  FreeAndNil(MyForm); 
end;
于 2009-05-27T16:53:25.763 回答