【发布时间】:2023-03-21 18:24:01
【问题描述】:
我想知道释放充满记录的 TList 的最佳方法。
我有以下记录:
type
TPkBill = record
PkBill: integer;
Constructor Create(c_PkBill: integer);
constructor TPkBill.Create(c_PkBill: integer);
begin
PkBill := c_PkBill;
end;
我创建列表并用记录填充它:
procedure TfrmProject.lvBillDblClick(Sender: TObject);
var
i, iCount: integer;
item: TListItem;
oPkBill: TPkBill;
lstPkBill: Tlist;
begin
iCount := 0;
lstPkBill:= TList.Create;
//if an item is selected in lv
if (lvBill.ItemIndex = -1) then begin exit; end
else
begin
//Loop through all items and get selected item
for i := 0 to lvBill.Items.Count - 1 do
begin
item := lvBill.Items.Item[i];
if(item.Selected = true)then
begin
//create new item
oPkBill := TPkBill.Create(StrToInt(lvBill.Items[i].Caption));
//add it to a list
lstPkBill.Add(TObject(oPkBill));
//add up
iCount := iCount +1;
end;
end;
//Now we have a list ok pkBill
if(iCount > 1)then //other stuff I do
end
我希望能够释放 TList 并释放记录。
这是我已经尝试过的:
for i := 0 to lstPkBill.Count - 1 do
begin
//TObject(TPkBill(lstPkBill[i])).Free; //Acces violation at adress..
//FreeMem(TPkBill(lstPkBill[i])); //Incompatible types
//FreeMem(TObject(lstPkBill[i])); //Incompatible types
end;
lstPkBill.Clear;
FreeAndNil(lstPkBill);
感谢您的帮助,不胜感激!
【问题讨论】:
-
除了调用 record 构造函数不会像 class 构造函数那样在堆上分配记录。此代码将基于堆栈的 记录实例放入
TList。没有什么可以释放的。 -
您的代码只能在 32 位平台上编译,因为它依赖于
SizeOf(TPkBill) = 4的事实。我敢打赌你没有意识到这一点。 -
记录构造器是撒旦的作品,永远不应该被使用。他们让你认为你已经在堆上分配了一些东西,或者需要调用
Free。假装你从未听说过它们。 -
@DavidHeffernan 我什至不知道什么是 32 位平台,但我会查一下,谢谢!在 TLama,感谢您的提议,但我尝试了 RemyL。回答,它奏效了。但我敢打赌它也可以做到这一点!
-
如果你可以使用泛型,你应该这样做。你的代码会更简单,更安全。不易泄漏。雷米的回答很好,也很直接,但它可能不是解决你潜在问题的最佳方法。
标签: delphi