0

我只是想知道我是否正在做一些可能不好的事情,尽管这对我来说似乎是一个非常实用的解决方案......

我有两种用户必须通过的表格。用户单击一个按钮并弹出 form1。用户按下 OK 并弹出第二个。用户再次单击确定,屏幕消失。或者用户单击重试,屏幕返回到第一个。两个屏幕的大小完全不同,信息也不同。

所以我想出了这个代码:

  Form1 := TForm1.Create(SharedData);
  Form2 := TForm2.Create(SharedData);
  repeat
    ModalResult := Form1.ShowModal;
    if (ModalResult = mrOK) then ModalResult := Form2.ShowModal;
  until (ModalResult <> mrRetry);
  Form1.Release;
  Form2.Release;

我已经测试了这段代码,它似乎很有魅力。在此代码中,SharedData 是一个对象,其中包含由两种表单操作的数据。我在创建两个表单之前创建了这个对象,当 ModalResult==mrOK 我只是将数据写回数据库。

问题是,虽然我认为这是处理两种形式之间翻转的干净解决方案,但我不记得以前见过类似这种结构的东西。当然,我是天才。(至少,我 Ego 告诉我我是。)但是是否有反对使用这段代码的东西,或者它就可以了吗?

4

2 回答 2

2

如果代码完成了它应该做的事情,我认为这很好。我以前也没有见过类似的东西,但它在做什么很明显......在我的书中,这比盲目地跟随别人的工作要好得多。:-)

于 2009-09-24T12:46:20.987 回答
1

我看不出代码有什么问题。但是,我确实质疑将 SharedData 传递给两种形式的构造函数。除非您重写了构造函数(也使用 reintroduce),否则 TForm.Create() 的参数接受所有者;该所有者负责释放其拥有的对象。由于您自己释放它们,因此无需分配所有者;只需将 nil 传递给对 Create() 的调用,以避免保存引用的开销,当一个人被释放以删除引用时访问拥有的对象列表等。

此外,Release 旨在从控件本身的事件处理程序中调用,例如在按钮单击事件中。它确保在实际释放控件之前处理所有待处理的消息,以避免 AV。再次以您现在的方式使用它会增加不必要的开销,因为您没有在事件处理程序中使用它们。您可以放心地使用 Form1.Free;反而。

为了阐明 Release 的使用,它用于 Form 本身的代码中。例如,如果您在表单上有一个按钮,并且您希望单击该按钮以释放表单,则使用 Release:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Self.Release;
  Close;
end;

这允许按钮单击以释放表单,但确保随后对 Close 的调用首先运行。如果您使用 Free 而不是上面的 Release,您最终可能会在不存在的 Form1 上调用 Close。(有可能它仍然可以,因为上面的代码很愚蠢;表单仍将驻留在内存中。不过,这仍然是个坏主意。)

于 2009-09-24T14:05:39.453 回答