2011-06-29 6 views
5

मैं सिर्फTObjectList <T> क्यों है? मुक्त ऑब्जेक्ट्स साफ़ करें?

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

वस्तु मुक्त नहीं है कि देखा। स्रोत कोड को देखते हुए ऐसा लगता है कि अधिसूचना Clear में दर्ज की गई है (TList <T> से विरासत में मिली)।

मेरा प्रश्न: क्या यह जानबूझकर है? क्या कोई कारण है कि कोई Clear के मामले में इन अधिसूचनाओं को प्राप्त नहीं करना चाहता है? या इसे संग्रह कक्षाओं में एक बग के रूप में माना जा सकता है?

संपादित

जाता है कि कोई मुझे TMyObject नाशक, जो निर्माता में जाने के लिए चाहिए था की चोटी पर लाइन

inherited Create; 

डाल दिया। यही कारण है कि मुझे मेमोरी लीक की सूचना मिली है जो TObjectList की तरह दिख रहा था आइटम को मुक्त नहीं कर रहा था। और स्रोत पर एक नज़र ने मुझे विश्वास दिलाया (मैं Count संपत्ति द्वारा फंस गया था)। फिर भी आपकी सहायता के लिए धन्यवाद!

+1

जंगली अनुमान: क्या आपने 'TMyObject.Destroy' को 'ओवरराइड' के रूप में चिह्नित किया है? –

+2

आप कैसे माप रहे हैं कि वस्तु मुक्त नहीं होती है? –

उत्तर

15

जब आप .Clear पर कॉल करते हैं तो सूची स्वामित्व वाली वस्तुओं को मुक्त करती है। आपके पास एक परीक्षण त्रुटि है। नीचे दिए गए कोड नमूना, डेल्फी XE पर लिखा, यह प्रदर्शित करता है:

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

TList<T>.Clear में कोड को धोखा दे रहा है, क्योंकि Count वास्तव में एक संपत्ति है। SetCount() पर देखें, फिर DeleteRange() पर देखें और DeleteRange प्रक्रिया के अंत में आपको Notify(oldItems[i], cnRemoved) के लिए कोड दिखाई देगा।


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 कॉल DeleteRange काम करने के लिए। DeleteRange का अंतिम भाग को cnRemoved से गुज़रने वाले सभी आइटमों के आसपास चलता है।

कोड का आपका विश्लेषण इस प्रकार गलत है। cnRemoved अधिसूचना विधिवत वितरित और स्वामित्व वाली वस्तुओं को मुक्त कर दिया गया है।

+2

एह। मेरे उत्तर से उद्धरण, 33 मिनट पहले आपके लिए: '"टीएलआईस्ट में कोड। क्लीयर धोखा दे रहा है, क्योंकि गणना वास्तव में एक संपत्ति है। SetCount() को देखें, फिर DeleteRange() देखें और आप के लिए कोड देखेंगे DeleteRange प्रक्रिया के अंत में सूचित करें (oldItems [i], cnRemoved)। "' –

+1

@ कोसमैन मुझे पता है। लेकिन आपके उत्तर में कोड का भार है जो उस संदेश को अव्यवस्थित करता है। जैसा कि आप जानते हैं मुझे संक्षिप्त उत्तर पसंद है। –

+0

आपका तर्क अच्छा है, और आपका उत्तर सही है, लेकिन मुझे कॉस्मीन का जवाब पसंद है क्योंकि इसमें नमूना कोड है। फिर भी मैं दोनों पर +1 करता हूं। –

संबंधित मुद्दे