代码之家  ›  专栏  ›  技术社区  ›  Thomas Mueller

从TobjectList中提取对象

  •  2
  • Thomas Mueller  · 技术社区  · 16 年前

    我有一个tobjectList,其ownsObjects=true。它包含相当多的对象。现在,我想从该列表中删除索引IDX处的对象,而不释放它。

    提取方法是唯一的选择吗?

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

    所有其他的方法似乎都能释放物体。我正在寻找一种更有效的方法,因为我已经知道对象的索引,所以每次都不进行线性搜索。有点像超载…

    ExtractedObject := TheList.Extract(Idx);

    …不存在。

    6 回复  |  直到 16 年前
        1
  •  8
  •   skamradt    16 年前

    为什么不将ownsObjects设置为false,删除对象,然后再次设置为true?

        2
  •  1
  •   Steve    16 年前

    如果您查看要删除的代码,它是导致释放的notify方法。

    这应该有效:

      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;
    
        3
  •  1
  •   Toon Krijthe    16 年前

    这就是课堂助手可以发挥作用的地方。

    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);
    
        4
  •  1
  •   Vegar    16 年前

    建议的helperclass(由gamecat提供)将导致与thomas希望摆脱的查找相同的结果。

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

    我建议你做些类似的事情:

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

    这将为您提供与extract()一样的对象,然后将其从列表中删除,而不进行任何查找。现在你可以把它放在一个方法中,比如helperclass或subclass,或者任何你喜欢的地方。

        5
  •  0
  •   gorsky    16 年前

    我以前不使用Delphi/C++Builder,但尽我所能,这是唯一的方法。 我的建议是改用tlist,并在需要时手动删除对象。

        6
  •  0
  •   Despatcher    16 年前

    有什么问题吗?

    extractedObject:=textracedObject.create;
    extractedObject.assign(列表[idx]);
    删除列表(idx);

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

    推荐文章