डेल्फी में डिफ़ॉल्ट रूप से, सभी संदर्भों को या तो कर रहे हैं:
- weak references
pointer
के लिए और class
उदाहरण;
- स्पष्ट प्रतिलिपि निम्न स्तर मूल्य प्रकार के लिए
integer, Int64, currency, double
या record
की तरह (और पुराने object
या shortstring
हटा दिया गया);
- copy-on-write उच्च स्तरीय मूल्य प्रकार के लिए reference counting साथ (जैसे
string, widestring, variant
या गतिशील सरणी);
- मजबूत संदर्भ
interface
उदाहरणों के लिए संदर्भ गणना के साथ;
मजबूत संदर्भ गिनती के साथ मुख्य मुद्दा संभावित परिपत्र संदर्भ समस्या है। ऐसा तब होता है जब interface
के पास एक मजबूत संदर्भ है, लेकिन लक्ष्य interface
पर एक मजबूत सूचक वापस मूल है। यहां तक कि जब सभी अन्य संदर्भ हटा दिए जाते हैं, तब भी वे एक दूसरे के पास रहेंगे और जारी नहीं किए जाएंगे। यह अप्रत्यक्ष रूप से, ऑब्जेक्ट्स की एक श्रृंखला द्वारा भी हो सकता है, जिसमें श्रृंखला में आखिरी वस्तु हो सकती है जो पहले की वस्तु को संदर्भित करती है।
उदाहरण के लिए निम्नलिखित इंटरफ़ेस परिभाषा देखें:
procedure TParent.SetChild(const Value: IChild);
begin
FChild := Value;
end;
procedure TChild.SetParent(const Value: IParent);
begin
FParent := Value;
end;
डेल्फी में, संदर्भ कॉपी चर का सबसे सामान्य प्रकार (यानी संस्करण, गतिशील:
IParent = interface
procedure SetChild(const Value: IChild);
function GetChild: IChild;
function HasChild: boolean;
property Child: IChild read GetChild write SetChild;
end;
IChild = interface
procedure SetParent(const Value: IParent);
function GetParent: IParent;
property Parent: IParent read GetParent write SetParent;
end;
निम्नलिखित कार्यान्वयन निश्चित स्मृति रिसाव हो जाएगा सरणी या स्ट्रिंग) कॉपी-ऑन-राइट लागू करके इस समस्या को हल करें। दुर्भाग्यवश, यह पैटर्न इंटरफ़ेस पर लागू नहीं है, जो मान ऑब्जेक्ट्स नहीं हैं, लेकिन संदर्भ ऑब्जेक्ट्स, कार्यान्वयन कक्षा से बंधे हैं, जिन्हें कॉपी नहीं किया जा सकता है।
ध्यान दें कि कचरा कलेक्टर आधारित भाषाओं (जावा या सी #) की तरह इस समस्या से, जब से वृत्तीय संदर्भ उनकी स्मृति मॉडल के आधार पर नियंत्रित किया जाता है ग्रस्त नहीं है: वस्तुओं जीवन भर स्मृति प्रबंधक द्वारा विश्व स्तर पर बनाए रखा है। बेशक, यह स्मृति उपयोग में वृद्धि करेगा, आवंटन और असाइनमेंट के दौरान अतिरिक्त कार्रवाइयों के कारण प्रक्रिया को धीमा कर देगा (सभी ऑब्जेक्ट्स और उनके संदर्भ आंतरिक सूचियों में बनाए रखा जाना चाहिए), और कचरा कलेक्टर कार्रवाई में प्रवेश करते समय एप्लिकेशन को धीमा कर सकता है।
कोई कचरा-संग्रह (जैसे डेल्फी) वाले भाषाओं के साथ एक आम समाधान कमजोर पॉइंटर्स का उपयोग करना है, जिसके द्वारा इंटरफ़ेस को संदर्भ गणना में वृद्धि किए बिना किसी संपत्ति को असाइन किया गया है। आसानी से एक कमजोर सूचक बनाने के लिए आदेश में, निम्न फ़ंक्शन का उपयोग किया जा सकता है:
procedure SetWeak(aInterfaceField: PIInterface; const aValue: IInterface);
begin
PPointer(aInterfaceField)^ := Pointer(aValue);
end;
इसलिए, यह इस तरह के रूप में इस्तेमाल किया जा सकता है:
procedure TParent.SetChild(const Value: IChild);
begin
SetWeak(@FChild,Value);
end;
procedure TChild.SetParent(const Value: IParent);
begin
SetWeak(@FParent,Value);
end;
आप my blog post about weak references in Delphi पढ़ने की कोशिश कर सकते हैं - और उसके संबंधित स्रोत कोड: हमने सीधे कमजोर संदर्भ लागू किया है, और डेल्फी 6 से XE2 तक कमजोर संदर्भ इंटरफ़ेस "शून्यिंग" को कार्यान्वित किया है।
वास्तव में, कुछ मामलों में, आपको इंटरफ़ेस कमजोर फ़ील्ड को nil
पर सेट करने की आवश्यकता होगी, यदि आप किसी भी एक्सेस उल्लंघन उल्लंघन से बचने के लिए अपने बच्चे के सामने संदर्भ उदाहरण जारी करते हैं। इसे "ज़ीरोइंग कमजोर पॉइंटर्स" कहा जाता है, और Apple implemented with the ARC model, और हमने डेल्फी में लागू करने का प्रयास किया।
विवरण के लिए +1 और अपने प्रोफ़ाइल चित्र –
@JanDoggen: :-) पशु हमेशा मेरी पसंदीदा मपेट –