应用程序通过调用相同的表单 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;