2008-11-12 5 views
2

OwnsObjects = true 인 TObjectList가 있습니다. 여기에는 꽤 많은 객체가 포함되어 있습니다. 이제 그 목록에서 인덱스 Idx에있는 객체를 해제하지 않고 제거하려고합니다.TObjectList에서 개체 추출

Extract 메서드가 유일한 옵션입니까?

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

다른 모든 방법

개체를 무료로 보인다. 나는 이미 객체의 인덱스를 알고 있기 때문에 매번 선형 검색을하지 않고 좀 더 효율적인 것을 찾고 있습니다. 존재하지 않는 오버로드 같은 뭔가 ...

ExtractedObject := TheList.Extract(Idx);

....

답변

8

왜 OwnsObjects를 false로 설정하지 않고 삭제를 수행 한 다음 다시 true로 설정해야하나요?

+0

너무 쉽습니다 .-) 감사합니다. –

0

저는 델파이/C++ 빌더를 사용하고 있습니다.하지만 지금까지는 그럴 수있는 방법이 없습니다. 제 제안은 대신 TList를 사용하고 필요할 때 수동으로 개체를 삭제하는 것입니다.

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; 

이제 사용할 수 있습니다 유용 할 수있는

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; 
1

이입니다

MyObjList.ExtractByIndex(MyIndex); 
+0

불행히도 나는 이미 객체의 색인을 새로운 추출 함수에 전달 했음에도 불구하고 원래 추출 함수에서 선형 검색을 수행합니다. 하지만 이것을 OwnsObjects = False/True와 결합하면 트릭을해야합니다. –

1

제안 helperclass을 (Gamecat에 의해)합니다 토마스가 없애기를 원하는 것과 동일한 조회를하게된다.

원본을 살펴보면 Extract()가 실제로하는 것을 볼 수 있으며 동일한 접근법을 사용할 수 있습니다. 이것은 않습니다) (추출, 당신에게 객체를 줄 것이다

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

하고 어떤 조회없이, 목록에서 삭제 :

나는 TIS 같은 것을 제안합니다. 이제이 메소드를 헬퍼 클래스 또는 서브 클래스 또는 원하는 곳의 메소드에 넣을 수 있습니다.

+0

아쉽게도 항목에 NIL 지정하면 자동으로 해제되므로이 기능이 작동하지 않습니다. –

+0

나는 completly 그것을 간과했지만, TList는 public 속성 List : PPoinerList를 통해 linkedlist에 대한 직접적인 액세스를 제공합니다. 목록 변경 [idx] : = nil list.List^[i] : = nil; 해결책은 다시 소리가 나야합니다. – Vegar

0

아무것도 문제 :

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

목록을 검색하는 데는 시간이 필요하지만 목록 검색에는 필요하지 않습니다. 효율성은 객체의 크기에 따라 달라집니다. -v는 목록의 크기입니다.

+0

이러한 접근 방식을 사용하려면 개체가 TPersistent에서 내려 와서 Assign 메서드를 제대로 구현해야합니다. –