应用程序通过调用相同的表单 5 次而挂起。前 4 次工作非常好,第五次应用程序挂起
App hangs by calling same Form 5 times. First 4 times work very nice, fifth time app hangs
我刚开始开发一个有两种形式的移动应用程序,FRM_Main
(主窗体)和 FRM_Party
(派对窗体)。我们可以通过单击图像从 FRM_Main
打开 FRM_Party
。图片上的代码是:
procedure TFRM_Main.IMAGE_PartyClick(Sender: TObject);
begin
FRM_Party := TFRM_Party.Create(Application);
FRM_Party.Show;
end;
现在,当 FRM_Party
调用 OnActivate
事件时,我正在 TMSFMXTableView
中加载一些数据。该代码是:
procedure TFRM_Party.FormActivate(Sender: TObject);
var
TableView : TTMSFMXTableViewItem;
I : Integer;
begin
if Class_My_Pro_and_func.Func_DataBaseConnection then // Checks wethere database connection is active or not if not then it connect with database and returns bool value.
Begin
UniQuery.Close;
UniQuery.SQL.Clear;
UniQuery.SQL.Text := 'select * from db_stock.tbl_party where Reg_ID = :Reg_ID and Party_Delete <> :Party_Delete order by Party_Name ';
UniQuery.ParamByName('Reg_ID').AsInteger := d_Glob_Reg_ID;
UniQuery.ParamByName('Party_Delete').AsString := 'F';
UniQuery.Open;
TABLEVIEW_Party.BeginUpdate;
if UniQuery.RecordCount > 0 then
begin
for I := 1 to UniQuery.RecordCount do
begin
TableView := TABLEVIEW_Party.Items.Add;
TableView.Caption := UniQuery.Fields[1].AsString;
TableView.Description := UniQuery.Fields[2].AsString + ' = ' + UniQuery.Fields[3].AsString;
TABLEVIEW_Party.EndUpdate;
UniQuery.Next;
end;
end
else
ShowMessage('No recored Found.');
End
end;
在 FRM_Party
上是一个后退按钮,可将用户带到 FRM_Main
。这个按钮代码是:
procedure TFRM_Party.BTN_Party_BackClick(Sender: TObject);
begin
try
UniQuery.Connection.Close; // Closing Query connection
DB_Connection.Disconnect; // Disconnecting database
FreeAndNil(FRM_Party);
Close;
except
on E: Exception do
ShowMessage(E.Message);
end;
end;
FRM_Party
.
上面除了上面的代码,其他什么都没有写
现在,问题是当我 运行 移动应用程序和 opening/closing FRM_Party
一次又一次时,前 4 次 FRM_Party
效果很好,但第五次 FRM_Party
正常打开,但关闭时应用程序挂起。我通过关闭和打开应用程序尝试了很多次。每次结果都一样
谁能帮帮我?
在您的 OnActivate
处理程序中,如果 UniQuery.RecordCount
不完全为 1,则您对 TABLEVIEW_Party
上的 BeginUpdate()
和 EndUpdate()
的调用是不平衡的。您正在调用BeginUpdate()
在进入循环之前,这很好,但是你在循环内调用 EndUpdate()
,因此调用它的次数与你调用 BeginUpdate()
的次数不同。您需要将这些呼叫移动到同一级别,例如:
procedure TFRM_Party.FormActivate(Sender: TObject);
var
TableView : TTMSFMXTableViewItem;
I : Integer;
begin
if not Class_My_Pro_and_func.Func_DataBaseConnection then
Exit;
UniQuery.Close;
UniQuery.SQL.Text := 'select * from db_stock.tbl_party where Reg_ID = :Reg_ID and Party_Delete <> :Party_Delete order by Party_Name ';
UniQuery.ParamByName('Reg_ID').AsInteger := d_Glob_Reg_ID;
UniQuery.ParamByName('Party_Delete').AsString := 'F';
UniQuery.Open;
if UniQuery.RecordCount > 0 then
begin
TABLEVIEW_Party.BeginUpdate;
try
for I := 1 to UniQuery.RecordCount do
begin
TableView := TABLEVIEW_Party.Items.Add;
TableView.Caption := UniQuery.Fields[1].AsString;
TableView.Description := UniQuery.Fields[2].AsString + ' = ' + UniQuery.Fields[3].AsString;
UniQuery.Next;
end;
finally
TABLEVIEW_Party.EndUpdate;
end;
end
else
ShowMessage('No record Found.');
end;
此外,在您的后退按钮的 OnClick
处理程序中,您在调用 FreeAndNil(FRM_Party)
.
之后在 FRM_Party
上调用 Close()
在 RAD Studio 10.4 之前的移动平台上,object lifetime is managed by ARC。调用 FreeAndNil(FRM_Party)
实际上不会释放 FRM_Party
对象,它只是将 FRM_Party
变量设置为 nil
。该对象未被释放,因为 Application
仍然有一个对其的活动引用。
但是在 RAD Studio 10.4 之后,ARC is no longer used,所以调用 FreeAndNil(FRM_Party)
实际上会销毁对象。所以之后再调用 Close()
会使你的代码崩溃。
在 TForm
关闭时释放它的正确方法是使用它的 OnClose
事件,例如:
procedure TFRM_Party.FormDestroy(Sender: TObject);
begin
If FRM_Party = Self then
FRM_Party := nil;
end;
procedure TFRM_Party.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := TCloseAction.caFree;
end;
procedure TFRM_Party.BTN_Party_BackClick(Sender: TObject);
begin
UniQuery.Connection.Close;
DB_Connection.Disconnect;
Close;
end;
我刚开始开发一个有两种形式的移动应用程序,FRM_Main
(主窗体)和 FRM_Party
(派对窗体)。我们可以通过单击图像从 FRM_Main
打开 FRM_Party
。图片上的代码是:
procedure TFRM_Main.IMAGE_PartyClick(Sender: TObject);
begin
FRM_Party := TFRM_Party.Create(Application);
FRM_Party.Show;
end;
现在,当 FRM_Party
调用 OnActivate
事件时,我正在 TMSFMXTableView
中加载一些数据。该代码是:
procedure TFRM_Party.FormActivate(Sender: TObject);
var
TableView : TTMSFMXTableViewItem;
I : Integer;
begin
if Class_My_Pro_and_func.Func_DataBaseConnection then // Checks wethere database connection is active or not if not then it connect with database and returns bool value.
Begin
UniQuery.Close;
UniQuery.SQL.Clear;
UniQuery.SQL.Text := 'select * from db_stock.tbl_party where Reg_ID = :Reg_ID and Party_Delete <> :Party_Delete order by Party_Name ';
UniQuery.ParamByName('Reg_ID').AsInteger := d_Glob_Reg_ID;
UniQuery.ParamByName('Party_Delete').AsString := 'F';
UniQuery.Open;
TABLEVIEW_Party.BeginUpdate;
if UniQuery.RecordCount > 0 then
begin
for I := 1 to UniQuery.RecordCount do
begin
TableView := TABLEVIEW_Party.Items.Add;
TableView.Caption := UniQuery.Fields[1].AsString;
TableView.Description := UniQuery.Fields[2].AsString + ' = ' + UniQuery.Fields[3].AsString;
TABLEVIEW_Party.EndUpdate;
UniQuery.Next;
end;
end
else
ShowMessage('No recored Found.');
End
end;
在 FRM_Party
上是一个后退按钮,可将用户带到 FRM_Main
。这个按钮代码是:
procedure TFRM_Party.BTN_Party_BackClick(Sender: TObject);
begin
try
UniQuery.Connection.Close; // Closing Query connection
DB_Connection.Disconnect; // Disconnecting database
FreeAndNil(FRM_Party);
Close;
except
on E: Exception do
ShowMessage(E.Message);
end;
end;
FRM_Party
.
现在,问题是当我 运行 移动应用程序和 opening/closing FRM_Party
一次又一次时,前 4 次 FRM_Party
效果很好,但第五次 FRM_Party
正常打开,但关闭时应用程序挂起。我通过关闭和打开应用程序尝试了很多次。每次结果都一样
谁能帮帮我?
在您的 OnActivate
处理程序中,如果 UniQuery.RecordCount
不完全为 1,则您对 TABLEVIEW_Party
上的 BeginUpdate()
和 EndUpdate()
的调用是不平衡的。您正在调用BeginUpdate()
在进入循环之前,这很好,但是你在循环内调用 EndUpdate()
,因此调用它的次数与你调用 BeginUpdate()
的次数不同。您需要将这些呼叫移动到同一级别,例如:
procedure TFRM_Party.FormActivate(Sender: TObject);
var
TableView : TTMSFMXTableViewItem;
I : Integer;
begin
if not Class_My_Pro_and_func.Func_DataBaseConnection then
Exit;
UniQuery.Close;
UniQuery.SQL.Text := 'select * from db_stock.tbl_party where Reg_ID = :Reg_ID and Party_Delete <> :Party_Delete order by Party_Name ';
UniQuery.ParamByName('Reg_ID').AsInteger := d_Glob_Reg_ID;
UniQuery.ParamByName('Party_Delete').AsString := 'F';
UniQuery.Open;
if UniQuery.RecordCount > 0 then
begin
TABLEVIEW_Party.BeginUpdate;
try
for I := 1 to UniQuery.RecordCount do
begin
TableView := TABLEVIEW_Party.Items.Add;
TableView.Caption := UniQuery.Fields[1].AsString;
TableView.Description := UniQuery.Fields[2].AsString + ' = ' + UniQuery.Fields[3].AsString;
UniQuery.Next;
end;
finally
TABLEVIEW_Party.EndUpdate;
end;
end
else
ShowMessage('No record Found.');
end;
此外,在您的后退按钮的 OnClick
处理程序中,您在调用 FreeAndNil(FRM_Party)
.
FRM_Party
上调用 Close()
在 RAD Studio 10.4 之前的移动平台上,object lifetime is managed by ARC。调用 FreeAndNil(FRM_Party)
实际上不会释放 FRM_Party
对象,它只是将 FRM_Party
变量设置为 nil
。该对象未被释放,因为 Application
仍然有一个对其的活动引用。
但是在 RAD Studio 10.4 之后,ARC is no longer used,所以调用 FreeAndNil(FRM_Party)
实际上会销毁对象。所以之后再调用 Close()
会使你的代码崩溃。
在 TForm
关闭时释放它的正确方法是使用它的 OnClose
事件,例如:
procedure TFRM_Party.FormDestroy(Sender: TObject);
begin
If FRM_Party = Self then
FRM_Party := nil;
end;
procedure TFRM_Party.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := TCloseAction.caFree;
end;
procedure TFRM_Party.BTN_Party_BackClick(Sender: TObject);
begin
UniQuery.Connection.Close;
DB_Connection.Disconnect;
Close;
end;