2011-06-29 10 views
5

Sadece TObjectList <T> Neden serbest nesneleri temizlemiyorsunuz?

var 
    ObjList : TObjectList <TMyObject>; 
... 
ObjList := TObjectList <TMyObject>.Create (True); 
ObjList.Add (TMyObject.Create); 
ObjList.Clear; 

nesne serbest olmadığını fark ettik. Kaynak koduna bakarak, Clear ( TList <T>'dan miras alınan) hiçbir cnRemoved bildiriminin tetiklenmediği anlaşılıyor.

Sorum: Bu kasıtlı mi? Clear durumunda bu bildirimleri almak istemeyen bir neden var mı? Veya bu toplama sınıflarında bir hata olarak kabul edilebilir mi?

DÜZENLEME

bir ben yapıcı gitmek gerekiyordu TMyObject destructor, üstüne bir çizgi

inherited Create; 

koymak çıkıyor. Bu yüzden, TObjectList'un öğeleri serbest bırakmadığını gösteren bellek sızıntıları bildirildi. Ve kaynaklara bir bakış beni ikna etti (Count mülkiyeti tarafından kapana kısılmıştım). Yine de yardımın için teşekkürler! Eğer .Clear çağırdığınızda

+1

Yabani tahminim: Eğer 'override' olarak' TMyObject.Destroy' işaretlenmiş mı? –

+2

Nesnenin serbest kalmamasını nasıl ölçüyorsunuz? –

cevap

15

liste olunan nesneler serbest bırakır. Bir test hatasının var. Delphi XE yazılı aşağıda kod örneği, bu görüntüler: TList<T>.Clear kodu aldatıcı

Calling CLEAR 
Object deleted. 
Object deleted. 
After CLEAR. Press ENTER to free L and Exit. 

, Count aslında bir özelliktir çünkü. Sonra DeleteRange() bakmak ve DeleteRange prosedürün sonunda Notify(oldItems[i], cnRemoved) için kod göreceksiniz, SetCount() bak.


program Project3; 

{$APPTYPE CONSOLE} 

uses SysUtils, Generics.Collections; 

type 
    TDelObject = class 
    public 
    destructor Destroy;override; 
    end; 

{ TDelObject } 

destructor TDelObject.Destroy; 
begin 
    WriteLn('Object deleted.'); 
    inherited; 
end; 

var L:TObjectList<TDelObject>; 

begin 
    L := TObjectList<TDelObject>.Create(True); 
    L.Add(TDelObject.Create); 
    L.Add(TDelObject.Create); 
    WriteLn('Calling CLEAR'); 
    L.Clear; 
    WriteLn('After CLEAR. Press ENTER to free L and Exit.'); 
    Readln; 
    L.Free; 
end. 
8

TList<T>.Clear aramalar DeleteRange işi yapmak için. DeleteRange'un son kısmı, Notify'u cnRemoved geçerek çağıran öğelerin tümünü çalıştırır. kod

Sizin analiz böylece yanlış. cnRemoved bildirimi usulüne uygun olarak teslim edilir ve sahip olunan nesneler serbest bırakılır.

+2

Ehh. cevabım alıntı önceki sizinkine 33 dakika: '" tlist .Clear aldatıcı kod, Kont aslında bir özellik SetCount() bak, çünkü o zaman DeleteRange (bakmak) ve sizin için kodunu göreceksiniz. DeleteRange prosedürünün sonunda (oldItems [i], cnRemoved) bildir. " –

+1

@Cosmin Biliyorum. Ama cevabın o mesajı karıştıran bir sürü kod var. Bildiğiniz gibi özlü cevapları severim. –

+0

Mantığınız iyi ve cevabınız doğru, fakat ben Cosmin'in cevabını tercih ediyorum çünkü örnek kodu var. Yine de her ikisinde de +1. –