我只是想知道我是否会做一些可能不好的事情,虽然这对我来说似乎是一个非常实用的解决方案......
我有两种形式,用户必须通过这两种形式。用户单击按钮并弹出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时,我只是将数据写回数据库。
问题是,虽然我认为这是处理两种形式之间翻转的一种干净的解决方案,但我记不起以前曾经看过类似这种结构的东西。当然,我是天才。 (至少,我自我告诉我自己。)但是有没有什么可以反对使用这段代码或者它没关系?
答案 0 :(得分:2)
如果代码符合预期,我认为没关系。我之前没有看到任何类似的东西,但很明显它正在做什么......在我的书中,它远比盲目地跟随其他人的工作要好得多。 : - )
答案 1 :(得分:1)
我没有看到代码有任何问题。但是,我确实将SharedData传递给两个表单的构造函数。除非你重写构造函数(也使用重新引入),否则TForm.Create()的参数接受所有者;该所有者负责释放其拥有的对象。既然你自己解放了它们,就没有必要指定一个拥有者;只需将nil传递给对Create()的调用,以避免保存引用的开销,在释放一个对象列表时访问所拥有的对象列表,等等。
此外,Release旨在从控件本身的事件处理程序中调用,例如在按钮单击事件中。它确保在实际释放控件之前处理所有挂起的消息,以避免AV。以你的方式再次使用它会增加不必要的开销,因为你没有在事件处理程序中使用它们。你可以安全地使用Form1.Free;代替。
为了澄清Release的使用,它用于表单本身的代码。例如,如果表单上有一个按钮,并且您希望该按钮单击以使表单被释放,则使用Release:
procedure TForm1.Button1Click(Sender: TObject);
begin
Self.Release;
Close;
end;
这允许按钮单击以释放表单,但确保后续调用Close先运行。如果您使用Free而不是上面的Release,则最终可能会在不存在的Form1上调用Close。 (有可能它仍然可以,因为上面代码的愚蠢;表单仍然会驻留在内存中。但仍然是一个坏主意。)