我什么时候需要释放应用程序创建的数据模块?
When do I need to free a Data Module created by the Application?
我有如下代码:
begin
Application.Initialize;
Application.Title := 'Controle Bancário';
Application.CreateForm(T_DMEstagio, _DMEstagio);
Application.CreateForm(T_frmLogin, _frmLogin);
if (_frmLogin.ShowModal = 1) then
begin
FreeAndNil(_frmLogin);
Application.CreateForm(T_frmPrincipal, _frmPrincipal);
Application.Run;
end;
_DMEstagio.Free;
end.
如果我没有像在代码中那样显式释放 DM,我会得到一个访问冲突异常,但在另一个应用程序中,代码是这样的:
begin
Application.Initialize;
Application.Title := ' > Sistema de Gestão Comercial <';
if HPrevInst = 0 then
begin
Application.CreateForm(TFrmPrincipal, FrmPrincipal);
Application.CreateForm(TIBDM, IBDM);
Application.Run;
end ;
end.
我不需要释放 DM,我也没有遇到任何异常。这是为什么?
回答你的问题
"When do I need to free a Data Module created by the Application?"
永远不会。
使用 Application.CreateForm
方法创建的所有数据模块 and/or 表单将由 Application
拥有并自动处理。
不过看来,你的问题与自动销毁过程无关。以下代码应该可以解决您的问题,因为某些组件和 类 需要应用程序完成其完整的 initialization/running 周期才能正常销毁。 RXHook
可能就是其中之一。
begin
Application.Initialize;
Application.Title := 'Controle Bancário';
Application.ShowMainForm := false;
Application.CreateForm(T_DMEstagio, _DMEstagio);
Application.CreateForm(T_frmLogin, _frmLogin);
if (_frmLogin.ShowModal = 1) then
begin
FreeAndNil(_frmLogin);
Application.ShowMainForm := true;
Application.CreateForm(T_frmPrincipal, _frmPrincipal);
end
else Application.Terminate;
Application.Run;
end.
那么上面的代码到底发生了什么?
您正在尝试显示登录表单并根据登录结果继续运行您的应用程序或终止它。
请务必注意,您创建的第一个表格将变为 Application.MainForm
,如果该表格在 Application.Run
执行之前发布 Application.MainForm
将被设置回 nil
.这将确保下一个创建的表单可以成为主表单。
在您的情况下,这意味着 _frmLogin
将被设置为您的 Application.MainForm
。如果登录成功,则释放,_frmPrincipal
接管。但是如果登录不成功,执行Application.Run
时,_frmLogin
仍然是Application.MainForm
,会再次显示
这就是 Application.ShowMainForm
发挥作用的地方。当它设置为 false
时,Application.Run
将只是 运行 而不显示任何形式。在您的情况下,它将阻止 _frmLogin
再次出现。当然,在成功登录后,您希望将 Application.ShowMainForm
设置回 true
以确保应用程序正常启动。
在登录不成功的情况下调用 Application.Terminate
将确保您的应用程序退出应用程序主消息循环,该循环将从调用 Application.Run
开始并正常终止。
我有如下代码:
begin
Application.Initialize;
Application.Title := 'Controle Bancário';
Application.CreateForm(T_DMEstagio, _DMEstagio);
Application.CreateForm(T_frmLogin, _frmLogin);
if (_frmLogin.ShowModal = 1) then
begin
FreeAndNil(_frmLogin);
Application.CreateForm(T_frmPrincipal, _frmPrincipal);
Application.Run;
end;
_DMEstagio.Free;
end.
如果我没有像在代码中那样显式释放 DM,我会得到一个访问冲突异常,但在另一个应用程序中,代码是这样的:
begin
Application.Initialize;
Application.Title := ' > Sistema de Gestão Comercial <';
if HPrevInst = 0 then
begin
Application.CreateForm(TFrmPrincipal, FrmPrincipal);
Application.CreateForm(TIBDM, IBDM);
Application.Run;
end ;
end.
我不需要释放 DM,我也没有遇到任何异常。这是为什么?
回答你的问题
"When do I need to free a Data Module created by the Application?"
永远不会。
使用 Application.CreateForm
方法创建的所有数据模块 and/or 表单将由 Application
拥有并自动处理。
不过看来,你的问题与自动销毁过程无关。以下代码应该可以解决您的问题,因为某些组件和 类 需要应用程序完成其完整的 initialization/running 周期才能正常销毁。 RXHook
可能就是其中之一。
begin
Application.Initialize;
Application.Title := 'Controle Bancário';
Application.ShowMainForm := false;
Application.CreateForm(T_DMEstagio, _DMEstagio);
Application.CreateForm(T_frmLogin, _frmLogin);
if (_frmLogin.ShowModal = 1) then
begin
FreeAndNil(_frmLogin);
Application.ShowMainForm := true;
Application.CreateForm(T_frmPrincipal, _frmPrincipal);
end
else Application.Terminate;
Application.Run;
end.
那么上面的代码到底发生了什么?
您正在尝试显示登录表单并根据登录结果继续运行您的应用程序或终止它。
请务必注意,您创建的第一个表格将变为 Application.MainForm
,如果该表格在 Application.Run
执行之前发布 Application.MainForm
将被设置回 nil
.这将确保下一个创建的表单可以成为主表单。
在您的情况下,这意味着 _frmLogin
将被设置为您的 Application.MainForm
。如果登录成功,则释放,_frmPrincipal
接管。但是如果登录不成功,执行Application.Run
时,_frmLogin
仍然是Application.MainForm
,会再次显示
这就是 Application.ShowMainForm
发挥作用的地方。当它设置为 false
时,Application.Run
将只是 运行 而不显示任何形式。在您的情况下,它将阻止 _frmLogin
再次出现。当然,在成功登录后,您希望将 Application.ShowMainForm
设置回 true
以确保应用程序正常启动。
在登录不成功的情况下调用 Application.Terminate
将确保您的应用程序退出应用程序主消息循环,该循环将从调用 Application.Run
开始并正常终止。