如何解决循环释放多个动态创建的帧
我有一个程序,在其中一种形式上,我需要在运行时动态创建未指定数量的帧(由数据库搜索后的记录数确定)。我使用for循环完成了此操作,并且为每个新创建的框架分配了一个新名称,如下所示:
for K:=1 to qryAeroAir.RecordCount do
begin
frmFlightDisplay:=TfrmFlightDisplay.Create(frmBook);
frmFlightDisplay.Name:='frmFlightDisplay'+IntToStr(K);
frmFlightDisplay.Parent:=pnlBookingDisplay;
// Rest of code for frame properties
end;
这似乎很好用,但是在程序后面,我需要释放或销毁这些帧,然后再创建新帧(具有相同的循环),这就是我遇到的问题。
for I:=1 to qryAeroAir.RecordCount do
begin
TfrmFlightDisplay(FindComponent('frmFlightDisplay'+IntToStr(I))).Free;
end;
上面的代码给我一个错误“名称为frmFlightDisplay1的框架”已经存在,这使我相信这些框架实际上并没有被破坏。还有其他方法可以释放或破坏所有框架以防止这种情况发生吗?
解决方法
使用字符串操作管理动态创建的对象非常脆弱,而且性能不高。
一种更好的方法,恕我直言,是将帧存储在对象列表中。在表单类中声明一个私有字段(使用Generics.Collections
)
private
FFrames: TObjectList<TfrmFlightDisplay>;
并使用以下格式创建并销毁它:
procedure TForm1.FormCreate(Sender: TObject);
begin
FFrames := TObjectList<TfrmFlightDisplay>.Create(True {owns objects});
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FFrames.Free;
end;
然后,当您创建一个新框架时,将其放在此列表中,然后它将拥有它:
procedure TForm1.btnAddFlightDisplayClick(Sender: TObject);
var
frm: TfrmFlightDisplay;
begin
frm := TfrmFlightDisplay.Create(nil);
try
frm.Parent := Self;
// other code settings properties of frm
except
frm.Free;
raise;
end;
FFrames.Add(frm); // transfer of ownership
end;
要释放所有框架,只需将它们从列表中删除。由于列表拥有框架,因此将释放框架对象:
procedure TForm1.btnClearClick(Sender: TObject);
begin
FFrames.Clear;
end;
您的代码有什么问题?
但是我没有解释您的代码有什么问题。
我的猜是
- 实际错误消息是“名为frmFlightDisplay1的组件已经存在”,
- 该异常不是在您尝试删除框架时发生,而是在您尝试再次添加它们时发生,并且
-
frmBook
方法中没有添加和删除框架的代码块。
如果我的猜测是正确的,那么问题就在于您明确地将框架归frmBook
(框架构造函数提供的参数)所有,但是FindComponent
是{{1}的简写},如果未在Self.FindComponent
的方法中运行,则frmBook
不是Self
。因此,frmBook
将返回FindComponent
,而nil
将无效。 (幸运的是,即使Free
是X.Free
,X
也是安全的。)
因此,解决您的问题的快速方法是改写nil
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。