2

OwnsObjects = true の TObjectList があります。かなりの数のオブジェクトが含まれています。ここで、インデックス Idx のオブジェクトを解放せずに、そのリストから削除したいと考えています。

抽出方法は唯一のオプションですか?

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

他のすべてのメソッドは、オブジェクトを解放するようです。オブジェクトのインデックスを既に知っているので、毎回線形検索を行わない、もう少し効率的なものを探しています。過負荷のようなもの...

ExtractedObject := TheList.Extract(Idx);

...存在しません。

4

6 に答える 6

9

OwnsObjects を false に設定して削除し、再度 true に設定するのはなぜですか?

于 2008-11-12T13:57:43.273 に答える
1

(Gamecatによって)提案されたヘルパークラスは、Thomasが削除したいのと同じルックアップになります。

ソースを見ると、Extract()が実際に何をしているのかがわかり、同じアプローチを使用できます。

私はtisのようなものを提案します:

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

これにより、Extract()と同様にオブジェクトが提供され、ルックアップなしでリストから削除されます。これで、ヘルパークラスやサブクラスなど、好きな場所でこれをメソッドに入れることができます。

于 2008-11-12T21:05:43.787 に答える
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);
于 2008-11-12T15:12:45.463 に答える
1

delete のコードを見ると、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;
于 2008-11-12T14:45:58.513 に答える
0

少し前までは Delphi/C++Builder を使用していませんでしたが、覚えている限り、それが唯一の方法でした。私の提案は、代わりに TList を使用し、必要に応じてオブジェクトを手動で削除することです。

于 2008-11-12T13:45:08.963 に答える
0

問題がある場合:

ExtractedObject := TExtractedObject.Create;
ExtractedObject.Assign(Thelist[Idx]);
TheList.Delete(idx);

作成と割り当てには時間がかかりますが、リストの検索には時間がかかります。効率は、オブジェクトのサイズ、つまりリストのサイズに依存します。

于 2008-11-13T20:13:15.663 に答える