用释放对象替换 TObjectList 中的对象 (Delphi7)
replace an object in a TObjectList with freeing it (Delphi7)
我有一个包含很少元素的 TObjectList。我必须在同一项目中用一个新的替换其中一个(不改变计数)。我执行以下操作:
procedure TForm1.Button1Click(Sender: TObject);
var
TObj: TObjectList;
LPoint: TPPoint;
i: integer;
begin
TObj:= TObjectList.Create;
try
for i:= 0 to 3 do
begin
LPoint:= TPPoint.Create(i, i+ 1);
TObj.Add(LPoint);
end;
LPoint:= TPPoint.Create(21, 22);
TObj.Items[1]:= nil;
TObj.Items[1]:= LPoint;
for i:= 0 to 3 do
begin
ShowMessage(IntToStr(TPPoint(TObj.Items[i]).X));
end;
finally
TObj.Free;
end;
end;
我的问题是:如何释放内存中被替换的元素?帮助说 "an Objekt will be freed if his Index will be reassigned"。命令 TObj.Items[1]:= nil;
够了吗?
提前感谢您提供任何信息。
TObj.Items[1]:= nil;
TObj.Items[1]:= LPoint;
在这里你执行了两个任务,所以 class 尝试释放两个项目。
TObj.Items[1]:= nil;
此时,上一项是在您之前的循环中添加的 non-nil 引用。该对象因此被销毁。
TObj.Items[1]:= LPoint;
当这一行执行时,TObj.Items[1] = nil
等 Free
方法在 nil
上被调用。没有任何反应。
底线是您的代码过于复杂。你可以替换
TObj.Items[1]:= nil;
TObj.Items[1]:= LPoint;
和
TObj.Items[1]:= LPoint;
class会销毁当前存储在TObj.Items[1]
中的对象,然后用LPoint
替换它。随心所欲
TObjectList.Create() 在使用 OwnsObjects = true(默认行为)创建时负责其项目内存管理
我使用 Delphi XE7 对其进行了测试,所以我不能保证这与 Delphi 7 中的行为完全相同。例如,声明 TObj: TObjectList 而不指定类型是不可能的(不会编译).
我使用 TLabel 而不是 TPPoint,并重命名了变量以减少混淆。为了确保它被释放,我将 ReportMemoryLeaksOnShutdown := True 添加到我的 dpr。这绝对是确保您不会弄乱内存的必备条件。遗憾的是它出现在 Delphi 2006 年,所以它在 Delphi 7.
中不可用
这段代码替换了列表中的一个项目,没有任何内存泄漏:
procedure TForm3.Button1Click(Sender: TObject);
var
list: TObjectList<TLabel>;
listItem: TLabel;
i: integer;
begin
list:= TObjectList<TLabel>.Create();
try
for i:= 0 to 3 do
begin
listItem:= TLabel.Create(nil);
listItem.Caption := 'list item ' + IntToStr(I);
list.Add(listItem);
end;
listItem:= TLabel.Create(nil);
listItem.Caption := 'list item replaced';
list.Items[1]:= listItem;
for i:= 0 to 3 do
begin
ShowMessage(list.Items[i].Caption);
end;
finally
list.Free;
end;
end;
我有一个包含很少元素的 TObjectList。我必须在同一项目中用一个新的替换其中一个(不改变计数)。我执行以下操作:
procedure TForm1.Button1Click(Sender: TObject);
var
TObj: TObjectList;
LPoint: TPPoint;
i: integer;
begin
TObj:= TObjectList.Create;
try
for i:= 0 to 3 do
begin
LPoint:= TPPoint.Create(i, i+ 1);
TObj.Add(LPoint);
end;
LPoint:= TPPoint.Create(21, 22);
TObj.Items[1]:= nil;
TObj.Items[1]:= LPoint;
for i:= 0 to 3 do
begin
ShowMessage(IntToStr(TPPoint(TObj.Items[i]).X));
end;
finally
TObj.Free;
end;
end;
我的问题是:如何释放内存中被替换的元素?帮助说 "an Objekt will be freed if his Index will be reassigned"。命令 TObj.Items[1]:= nil;
够了吗?
提前感谢您提供任何信息。
TObj.Items[1]:= nil;
TObj.Items[1]:= LPoint;
在这里你执行了两个任务,所以 class 尝试释放两个项目。
TObj.Items[1]:= nil;
此时,上一项是在您之前的循环中添加的 non-nil 引用。该对象因此被销毁。
TObj.Items[1]:= LPoint;
当这一行执行时,TObj.Items[1] = nil
等 Free
方法在 nil
上被调用。没有任何反应。
底线是您的代码过于复杂。你可以替换
TObj.Items[1]:= nil;
TObj.Items[1]:= LPoint;
和
TObj.Items[1]:= LPoint;
class会销毁当前存储在TObj.Items[1]
中的对象,然后用LPoint
替换它。随心所欲
TObjectList.Create() 在使用 OwnsObjects = true(默认行为)创建时负责其项目内存管理
我使用 Delphi XE7 对其进行了测试,所以我不能保证这与 Delphi 7 中的行为完全相同。例如,声明 TObj: TObjectList 而不指定类型是不可能的(不会编译).
我使用 TLabel 而不是 TPPoint,并重命名了变量以减少混淆。为了确保它被释放,我将 ReportMemoryLeaksOnShutdown := True 添加到我的 dpr。这绝对是确保您不会弄乱内存的必备条件。遗憾的是它出现在 Delphi 2006 年,所以它在 Delphi 7.
中不可用这段代码替换了列表中的一个项目,没有任何内存泄漏:
procedure TForm3.Button1Click(Sender: TObject);
var
list: TObjectList<TLabel>;
listItem: TLabel;
i: integer;
begin
list:= TObjectList<TLabel>.Create();
try
for i:= 0 to 3 do
begin
listItem:= TLabel.Create(nil);
listItem.Caption := 'list item ' + IntToStr(I);
list.Add(listItem);
end;
listItem:= TLabel.Create(nil);
listItem.Caption := 'list item replaced';
list.Items[1]:= listItem;
for i:= 0 to 3 do
begin
ShowMessage(list.Items[i].Caption);
end;
finally
list.Free;
end;
end;