替换TObjectList中的对象并释放它(Delphi7)

时间:2017-02-17 08:42:37

标签: delphi tobjectlist

我有一个包含少量元素的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;

我的问题是:如何释放内存中被替换的元素?帮助说"如果他的指数将被重新分配,Objekt将被释放"。命令TObj.Items[1]:= nil;是否足够?

提前感谢任何信息。

2 个答案:

答案 0 :(得分:3)

TObj.Items[1]:= nil;
TObj.Items[1]:= LPoint;

在这里执行两项任务,因此课程会尝试释放两项。

TObj.Items[1]:= nil;

此时前一项是在前一循环中添加的非零引用。这个目标因此被摧毁。

TObj.Items[1]:= LPoint;

执行此行时,TObj.Items[1] = nil因此Free上会调用nil方法。没有任何事情发生。

底线是您的代码过于复杂。你可以替换

TObj.Items[1]:= nil;
TObj.Items[1]:= LPoint;

TObj.Items[1]:= LPoint;

该类将销毁当前存储在TObj.Items[1]中的对象,然后将其替换为LPoint。就像你想要的那样。

答案 1 :(得分:1)

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;