我正确吗?
我用在填充过程中创建的记录填充TStringlist中的对象。
我已经将TStringList.OwnsObjects设置为true。但是,当我关闭应用程序时,出现访问冲突。下面是我的代码的一部分。
type
PUsageData = ^TUsageData;
TUsageData = record
DeclaredIn: String;
LineNumber: Integer;
TotalUsage: Integer;
end;
...
var VarUsages: TStringList; // object contains a TUsageData record
procedure BuildUsageList;
var idx, idy, n,m: Integer;
sl: TStringList;
s,t: String;
rec: PUsageData;
begin
VarUsages.Clear;
sl:= TStringList.Create;
s := '';
// First make a list and create a record for each variable declared in program
for idx := 0 to IncludeList.Count -1 do begin
GetSource(IncludeList[idx], sl);
for idy := 0 to sl.Count -1 do begin
t := '';
t := CodeAnalyser.GetItems(sl[idy], caVariables);
if t > '' then begin
system.New(Rec);
rec.DeclaredIn := IncludeList[idx];
rec.LineNumber := idy;
rec.TotalUsage := 0;
VarUsages.AddObject(t, TObject(rec));
end;
end;
end;
end;
...
initialization
VarUsages := TStringList.Create;
VarUsages.OwnsObjects := true;
finalization
VarUsages.Free;
end.
我正在使用Delphi 10.1。
我还想知道清除StringList会发生什么。它会丢弃对象吗?
答案 0 :(得分:4)
您至少可以通过三种方式处理此问题:
由于您要存储记录的指针,而不是TObject
个后代,因此您不能依赖OwnsObjects
。将其设置为False
!
在Free
TStringList
之前,您应该手动Dispose
记录每条记录:
for I := 0 to VarUsages.Count - 1 do
Dispose(PUsageData(VarUsages.Objects[i]));
请注意,对PUsageData
的强制转换对于Dispose
的正常运行很重要。
由于您将OwnsObjects
设置为False
,因此字符串列表将不会尝试释放“对象”,因此您可以立即调用:
VarUsages.Free;
请注意,Dispose
将妥善完成记录的定案,包括其中的字符串。
注意:正如David Heffernan所说: 以及在销毁字符串列表时手动销毁,每当删除或修改项目时都必须这样做< / em>。这使另两个选择更具吸引力,IMO。
或者,您可以将TUsageData
变成一个简单的类(没有方法,没有属性,只有公共字段):
type
TUsageData = class
public
DeclaredIn: string;
LineNumber: Integer;
TotalUsage: Integer;
end;
然后,您可以将OwnsObjects
设置为True
,并让字符串列表来释放它们。该方案也适用于ARC受管目标。使用New
代替Rec := TUsageData.Create;
。据我所知,您可以使用相同的代码。
请使用TList<TUsageData>
之类的东西代替TUsageData
,而t
可以保留一条记录。无需使用指针。只需将TList<>
字符串也放入记录中即可。由于您正在处理记录,因此除了 Rec: TUsageData; // record!
...
t := CodeAnalyser.GetItems(sl[idy], caVariables);
if t > '' then
begin
Rec.t := t;
Rec.DeclaredIn := IncludeList[idx];
Rec.LineNumber := idy;
Rec.TotalUsage := 0;
VarUsages.Add(Rec);
本身以外,不需要释放任何东西。释放它也将需要完成其中的记录。
git