Delphi 从TObjectList中提取对象
我有一个TObjectList,OwnsObjects=true。它包含相当多的对象。现在我想从列表中删除索引Idx处的对象,而不释放它 提取方法是唯一的选择吗Delphi 从TObjectList中提取对象,delphi,tobjectlist,tlist,Delphi,Tobjectlist,Tlist,我有一个TObjectList,OwnsObjects=true。它包含相当多的对象。现在我想从列表中删除索引Idx处的对象,而不释放它 提取方法是唯一的选择吗 ExtractedObject:=TheList.Extract(TheList[Idx]) 所有其他方法似乎都可以释放对象。我正在寻找一种更高效的方法,它不会每次都进行线性搜索,因为我已经知道对象的索引。有点像超载的 ExtractedObject:=list.Extract(Idx) 。。。这是不存在的。我不久前没有使用Delphi
ExtractedObject:=TheList.Extract(TheList[Idx])代码>
所有其他方法似乎都可以释放对象。我正在寻找一种更高效的方法,它不会每次都进行线性搜索,因为我已经知道对象的索引。有点像超载的
ExtractedObject:=list.Extract(Idx)代码>
。。。这是不存在的。我不久前没有使用Delphi/C++Builder,但据我所知,这是唯一的方法。
我的建议是改为使用TList,并在需要时手动删除对象。为什么不将OwnsObjects设置为false,执行删除操作,然后再次将其设置为true?如果查看删除代码,则是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;
这是课堂助手可以发挥作用的地方
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;
建议的helperclass(由Gamecat提供)将产生Thomas希望摆脱的相同查找
如果您查看一下源代码,就可以看到Extract()的真正作用,然后使用相同的方法
我会建议一些类似tis的建议:
obj := list[idx];
list.list^[idx] := nil; //<- changed from list[idx] := nil;
list.delete(idx);
obj:=list[idx];
list.list^[idx]:=nil// 有什么问题吗
ExtractedObject:=TExtractedObject.Create
ExtractedObject.Assign(列表[Idx])
删除列表(idx)
创建和分配需要时间,但搜索列表不需要时间。效率取决于对象的大小-v-列表的大小。不幸的是,这仍然会在原始提取函数中进行线性搜索,即使我已经将对象的索引传递给了新的提取函数。但是我想将它与OwnsObjects=False/True结合起来应该可以达到目的。不幸的是,这也不起作用,因为将NIL指定给一个项会自动释放它。Oops。我完全忽略了这一点,但TList允许您通过公共属性列表PPoinerList直接访问linkedlist。将list[idx]:=nil更改为list.list^[i]:=nil;解决方案应该是合理的。这种方法要求对象从TPersistent下降,并正确地实现赋值方法
obj := list[idx];
list.list^[idx] := nil; //<- changed from list[idx] := nil;
list.delete(idx);