如何在运行时在 Firemonkey 中创建和销毁 TGrid — Android 和 iOS App Dev

How to Create and Destroy TGrid at Runtime in Firemonkey — Android and iOS App Dev

我有一个在运行时创建的 TGrid。该过程要求我在单击“添加项目并刷新”按钮重新创建之前销毁 TGrid。我注意到,如果我在重新创建 TGrid 之前不销毁它,那么沉重的开销会导致我的应用程序冻结超过 8 次或更多次。

我尝试了以下代码但无济于事:

procedure TformMain.AddItemRefreshClick(Sender: TObject);
var
  TGrid1 : TTGrid;
begin
  if Assigned(TGrid1) then
  begin
    TGrid1.DisposeOf;
    {TGrid1.Free;    Tried this also but not working}
    {TGrid1 := nil;  Tried this also but not working}
  end;

  TGrid1 := TTGrid.Create(formMain);
  With TGrid1 do
  begin
    Parent := formMain;
    Align := TAlignLayout.Client;
    Margins.Top := 5;
    Margins.Left := 5;
    Margins.Right := 5;
    Margins.Bottom := 5;
    ScrollBars.Visible := True;
    Header.Format.Font.Size := 11;
    Cells.Format.Font.Size := 11;
    TabOrder := 0;
  end;
end;

我在地址处遇到访问冲突...听起来是个错误!

有没有更简单的方法可以在运行时创建和销毁像 TGrid 这样的可视化组件?

您必须使用非局部变量来存储网格,以便在调用此方法之间保留其地址。

目前,TGrid1是一个局部变量。这实质上意味着它是每次调用例程时创建的变量。它的值不会在两次调用之间保存。而在Delphi中,非托管类型的局部变量没有被初始化,所以这基本上是一个随机指针。使用它非常危险! (而且 Assigned 对你没有帮助,因为随机指针很可能是非零的,因为它是......好吧,随机的。)

(顺便说一句,变量名 TGrid1 非常令人困惑,因为它以 T 开头。通常只有类型名称以 T 开头。)

所以改为在您的表单中添加一个私有字段 class:

  private
    FMyGrid: TGrid;

(我不知道class这个名字是:在你的Q里,你把TTeeGridTTGrid都写了。)

那你可以做

procedure TformMain.AddItemRefreshClick(Sender: TObject);
begin

  // Free old grid
  FreeAndNil(FMyGrid);

  // Create new grid
  FMyGrid := TGrid.Create(formMain);
  with FMyGrid do
  begin
    Parent := formMain;
    Align := TAlignLayout.Client;
    Margins.Top := 5;
    Margins.Left := 5;
    Margins.Right := 5;
    Margins.Bottom := 5;
    ScrollBars.Visible := True;
    Header.Format.Font.Size := 11;
    Cells.Format.Font.Size := 11;
    TabOrder := 0;
  end;

end;

FreeAndNil(FMyGrid) 基本上做 FMyGrid.Free 并且还将指针设置为 nil 这样你就不会以悬空指针结束,以防 TGrid.Create 构造函数应该引发异常。

此外,不需要 if Assigned(FMyGrid) then 部分,因为 FMyGrid.Free 会进行检查。

还要注意 FMyGrid 现在是 class 的成员,因此它从一开始就被初始化为 nil