Как создать и уничтожить TGrid во время выполнения в Firemonkey - разработчик приложений для Android и iOS
У меня есть 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, во время выполнения?
1 ответ
Вы должны использовать нелокальную переменную для хранения сетки, чтобы ее адрес сохранялся между вызовами этого метода.
В данный момент, TGrid1
это локальная переменная. По сути, это означает, что это переменная, которая создается каждый раз при вызове подпрограммы. Его значение не сохраняется между вызовами. А в Delphi локальные переменные неуправляемых типов не инициализируются, так что это в основном случайный указатель. Работать с ним очень опасно! (А такжеAssigned
не поможет вам, поскольку случайный указатель вполне может быть ненулевым, потому что он... ну, случайный.)
(Кстати, имя переменной TGrid1
очень сбивает с толку, поскольку начинается с T
. Обычно только имена типов начинаются сT
.)
Поэтому вместо этого добавьте частное поле в свой класс формы:
private
FMyGrid: TGrid;
(Я не знаю, что имя класса: в вашем Q вы пишете оба TTeeGrid
а также TTGrid
.)
Тогда ты можешь сделать
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
now является членом класса и поэтому инициализируется как nil
с самого начала.