从TObjectList中提取对象

时间:2008-11-12 13:38:46

标签: delphi tobjectlist tlist

我有一个带OwnsObjects = true的TObjectList。它包含很多对象。现在我想从该列表中删除索引Idx处的对象,而不释放它。

Extract方法是唯一的选择吗?

ExtractedObject := TheList.Extract(TheList[Idx]);

所有其他方法似乎都释放了对象。我正在寻找一些更高效的东西,每次都不进行线性搜索,因为我已经知道了对象的索引。像重载的......

ExtractedObject := TheList.Extract(Idx);

......不存在。

6 个答案:

答案 0 :(得分:8)

为什么不将OwnsObjects设置为false,删除,然后再将其设置为true?

答案 1 :(得分:1)

如果你看一下删除代码,那就是通知方法,它会导致释放。

这应该有效:

  TMyObjectList = Class(TObjectList)
  private
    fNotify: Boolean;
    { Private declarations }
    procedure EnableNotification;
    procedure DisableNotification;
  protected
    procedure Notify(Ptr: Pointer; Action: TListNotification); override;
  public
    constructor Create(AOwnsObjects: Boolean);overload;
    constructor Create; overload;
    function Extract(const idx : Integer) : TObject;
  end;


constructor TMyObjectList.Create(AOwnsObjects: Boolean);
begin
  inherited Create(AOwnsObjects);
  fNotify := True;
end;

constructor TMyObjectList.Create;
begin
  inherited Create;
  fNotify := True;
end;

procedure TMyObjectList.DisableNotification;
begin
  fnotify := False;
end;

procedure TMyObjectList.EnableNotification;
begin
  fNotify := True;
end;

function TMyObjectList.Extract(const idx: Integer) : TObject;
begin
  Result := Items[idx];
  DisableNotification;
  try
    Delete(idx);
  finally
    EnableNotification;
  end;
end;

procedure TMyObjectList.Notify(Ptr: Pointer; Action: TListNotification);
begin
 if fNotify then
   inherited;
end;

答案 2 :(得分:1)

这是课助手可以使用的地方

TObjectListHelper = class helper for TObjectList
  function ExtractByIndex(const AIndex: Integer): TObject;
end;

function TObjectListHelper.ExtractByIndex(const AIndex: Integer): TObject;
begin
  Result := Items[AIndex];
 if Result<>nil then
   Extract(Result);
end;

您现在可以使用:

MyObjList.ExtractByIndex(MyIndex);

答案 3 :(得分:1)

建议的helperclass(由Gamecat提供)将导致Thomas想要删除的相同查找。

如果您查看源代码,可以看到Extract()的确实做了什么,然后使用相同的方法。

我会建议像tis这样的东西:

obj := list[idx];
list.list^[idx] := nil;  //<- changed from list[idx] := nil;
list.delete(idx);

这会像Extract()那样为你提供对象,然后从列表中删除它,而不进行任何查找。现在你可以把它放在一个方法中,一个helperclass或子类,或者你喜欢什么。

答案 4 :(得分:0)

前段时间我没有使用Delphi / C ++ Builder,但据我所知,这是唯一的方法。 我的建议是改用TList,并在需要时手动删除对象。

答案 5 :(得分:0)

有什么问题:

ExtractedObject:= TExtractedObject.Create;
ExtractedObject.Assign(的thelist [IDX]);
TheList.Delete(IDX);

创建和分配需要时间,但不能搜索列表。效率取决于对象的大小-v-列表的大小。