2012-05-02 19 views
13

साफ़ करें मैं एक सूची में ऑब्जेक्ट्स को संग्रहीत करने के लिए उपयोग करने के बारे में थोड़ा उलझन में हूं। अब तक मैंने TList का उपयोग किया है और प्रत्येक आइटम को लूप में मुक्त कर दिया है। तब मैंने TObjectList की खोज की जो इसे Free से स्वचालित रूप से करता है। तब मैं TList.Clear के दस्तावेज़ से यह देखा:एक टीएलआईस्ट या टॉब्जेक्टलिस्ट

कॉल Clear आइटम सरणी खाली और स्थापित करने के लिए Count 0 पर Clear भी Items सरणी स्टोर करने के लिए इस्तेमाल किया स्मृति को मुक्त कर देते और Capacity को 0.

सेट

तो यह मूल रूप से वही है। तो

के लिए TList

mylist.Clear; 
myList.Free; 

TObjectList के लिए के रूप में ही है?

myList.Free; 

TObjectList केवल कक्षाओं के रूप में वस्तुओं के लिए उपयोग किया जा सकता है या मैं रिकॉर्ड स्टोर कर सकता हूं?

+1

आपके द्वारा उद्धृत किया गया हिस्सा केवल "मूल रूप से वही है" यदि आप TObjectList दस्तावेज़ को सावधानी से नहीं पढ़ते हैं: "यदि स्वामित्व वाली संपत्ति सत्य (डिफ़ॉल्ट) पर सेट की गई है, तो TObjectList किसी ऑब्जेक्ट को मुक्त करने, अपनी ऑब्जेक्ट्स की स्मृति को नियंत्रित करता है जब इसकी अनुक्रमणिका को फिर से सौंप दिया जाता है; जब इसे हटाएं, निकालें, या साफ़ करें विधि के साथ सूची से हटा दिया जाता है, या जब TObjectList इंस्टेंस स्वयं नष्ट हो जाता है। " टीएलिस्ट का दस्तावेज उस व्यवहार के बारे में कुछ भी नहीं कहता है। यह दो वर्गों के बीच मौलिक अंतर है। –

उत्तर

18

1. TList तत्वों, दोनों Clear या Free साथ खाली नहीं होगा।

aList.Clear;

aList.Items[] तत्वों को मुक्त किए बिना aList.Count := 0 सेट करेगा। तो आप स्मृति रिसाव करेंगे। आप इस तरह के रूप में एक स्पष्ट नि: शुल्क की आवश्यकता होगी:

for i := 0 to aList.Count-1 do 
    TObject(aList[i]).Free; 

लेकिन यह क्या TObjectList करता है ... :)

बारे TObjectList, यह कह रही है कि TObjectList.DestroyClear बुला रहा है के लायक है।

तो

aObjectList.Clear; 
aObjectList.Free; 

ठीक उसी

रूप
aObjectList.Free; 

2. रिकॉर्ड की एक सूची संग्रहीत करने के लिए, आप एक गतिशील सरणी का उपयोग कर सकते है।

आपको हमारे dynamic array wrapper के साथ सभी TList विधियां (और अधिक) मिलेंगे। वह है, Add/Delete/Clear/Count/IndexOf/Find ...

इसमें अंतर्निहित धारावाहिक सुविधाएं (बाइनरी या जेएसओएन में), स्वचालित सॉर्टिंग और तुलना (आरटीटीआई का उपयोग) है जो TList/TObjectList के साथ मौजूद नहीं है। डेल्फी 5 और बाद में।

डेल्फी के अधिक आधुनिक संस्करण के साथ, यदि आप किसी तृतीय-पक्ष लाइब्रेरी का उपयोग नहीं करना चाहते हैं, तो आप गतिशील सरणी को संभालने के लिए जेनेरिक का उपयोग कर सकते हैं।

+3

बस 'tobjectList' के बारे में एक स्पष्टीकरण। इसमें एक संपत्ति है: 'स्वामित्व ऑब्जेक्ट्स' (डिफ़ॉल्ट = सत्य) जो आइटम को हटाए जाने पर सूची में ऑब्जेक्ट को मुक्त किया जा रहा है, जो नियंत्रित करता है। –

+0

@LURD आप सही हैं। यह संपत्ति आसान हो सकती है, लेकिन भ्रामक भी हो सकती है: आप मान सकते हैं कि ऑब्जेक्ट मुक्त हो जाएंगे, लेकिन यदि आप कोड में कहीं भी 'OwnOjects: = false' सेट करते हैं (यहां तक ​​कि रनटाइम पर), तो आप आसानी से स्मृति या संसाधनों को रिसाव करेंगे: इसलिए देखभाल के साथ प्रयोग किया जाता है! मैं स्पष्ट 'टीएलआईस्ट/टॉब्जेक्टलिस्ट' अलगाव पसंद करता हूं। –

10

यह वही नहीं है TList.Clear केवल पॉइंटर्स को स्टोर करने के लिए आवंटित स्मृति को मुक्त करता है, न कि वे ऑब्जेक्ट्स को इंगित कर रहे हैं। मेमोरी लीक से बचने के लिए आपको स्मृति को मुक्त करने की आवश्यकता है - जैसा कि आप कर रहे हैं - या TObjectList का उपयोग करें।

दूसरे प्रश्न का उत्तर देने के लिए, TObjectList रिकॉर्ड संग्रह का समर्थन नहीं करता है। उस मामले में आपको TList (या कुछ और) का उपयोग करने की आवश्यकता है।

+0

किसी 'टीएलआईस्ट' में रिकॉर्ड प्रबंधित करने के बारे में पता है हालांकि कुछ प्रयासों की आवश्यकता है। – NGLN

7

यदि आप डेल्फी के हाल के संस्करण का उपयोग कर रहे हैं तो मैं सुझाव देता हूं कि आप एक सामान्य सूची का उपयोग करें।

अभी जब आप सूची से ऑब्जेक्ट्स का उपयोग करते हैं तो आपको शायद बहुत सारे कास्टिंग करने की आवश्यकता होती है। एक सामान्य सूची के साथ आपको अब और ऐसा करने की ज़रूरत नहीं है।

उदाहरण के लिए अगर आपके पास:

TMyObject = class(TObject); 

तो फिर तुम बनाने के इस तरह सूची:

TMyObjectList = TObjectList<TMyObject>; 

Embarcadero विकी में एक लेख है:

http://docwiki.embarcadero.com/CodeExamples/XE8/en/Generics_Collections_TObjectList_(Delphi)

7

पढ़ें कि दस्तावेज़ क्या अधिक सावधानीपूर्वक कह ​​रहा है:

साफ़ भी आइटम सरणी

सरणी के अंदर अलग-अलग तत्वों द्वारा इस्तेमाल किया केवल सरणी खुद के लिए स्मृति मुक्त हो जाता है, नहीं स्मृति स्टोर करने के लिए इस्तेमाल किया स्मृति को मुक्त कर देते।

-1

वास्तव में TObjectList कोड contnrs.pas OwnObjects में कुछ भी नहीं देख रहा है। FOwnObjectsTObjectList के निजी भाग में घोषित एक चर है जिसे TObjectList कोड (केवल मान निर्दिष्ट करने के अलावा) में कहीं भी उपयोग नहीं किया जाता है, और इसमें कोई ओवरराइड Clear प्रक्रिया नहीं है।

तो मुझे स्मृति है कि यह मेमोरी को TList जैसा ही मुक्त करने के लिए आवश्यक है।

+1

संपत्ति 'TObjectList.OwnsObjects' डिफ़ॉल्ट रूप से सत्य है। सृजन के बाद आप संपत्ति मूल्य बदल सकते हैं। यदि यह संपत्ति 'TObjectList.Free' को कॉल करते समय सत्य है, तो सूची में सभी ऑब्जेक्ट स्वचालित रूप से हटा दिए जाएंगे। –