मुझे यकीन है कि हर कोई जानता है कर रहा हूँ के रूप में, एक वस्तु के प्रबंधन के लिए मानक तरीका इस तरह है:
A := TMyObject.Create;
try
A.DoSomething;
finally
A.Free;
end;
अगर वहाँ TMyObject.Create
में एक अपवाद तो नाशक बुलाया जाएगा और उसके बाद अपवाद उठाया है। उस स्थिति में A
को असाइन नहीं किया जाएगा।
जब आप एक से अधिक ऑब्जेक्ट है आप पैटर्न को दोहरा सकते हैं:
A := TMyObject.Create;
try
B := TMyObject.Create;
try
A.DoSomething;
B.DoSomething;
finally
B.Free;
end;
finally
A.Free;
end;
यह बहुत जल्दी एक मेस और इसलिए सवाल बन जाता है।
एक मानक चाल इस तथ्य का लाभ उठाने के लिए है कि Free
सुरक्षित रूप से nil
ऑब्जेक्ट संदर्भ पर कॉल किया जा सकता है।
A := nil;
B := nil;
try
A := TMyObject.Create;
B := TMyObject.Create;
A.DoSomething;
B.DoSomething;
finally
B.Free;
A.Free;
end;
यह मामूली कमजोरी है कि यह अपवाद B.Free
में उठाया जा रहा करने के लिए लचीला नहीं है है लेकिन यह एक विफलता की स्थिति है कि अनदेखा किया जा सकता के रूप में इस संबंध को अनुचित नहीं है। विनाशकों को अपवाद नहीं उठाना चाहिए। यदि वे करते हैं तो आपकी प्रणाली शायद अप्रत्याशित रूप से टूट जाती है।
उपरोक्त यह पैटर्न थोड़ा गन्दा हो सकता है क्योंकि अधिक ऑब्जेक्ट्स जोड़े गए हैं इसलिए मैं व्यक्तिगत रूप से निम्न सहायक विधियों का उपयोग करता हूं।
procedure InitialiseNil(var Obj1); overload;
procedure InitialiseNil(var Obj1, Obj2); overload;
procedure InitialiseNil(var Obj1, Obj2, Obj3); overload;
procedure FreeAndNil(var Obj1); overload;
procedure FreeAndNil(var Obj1, Obj2); overload;
procedure FreeAndNil(var Obj1, Obj2, Obj3); overload;
वास्तव में मेरे कोड में और भी पैरामीटर के साथ संस्करण हैं। रखरखाव की आसानी के लिए यह कोड स्वचालित रूप से एक छोटी पायथन लिपि से उत्पन्न होता है।
ये विधियां स्पष्ट तरीके से लागू की गई हैं, उदा।
procedure FreeAndNil(var Obj1, Obj2);
var
Temp1, Temp2: TObject;
begin
Temp1 := TObject(Obj1);
Temp2 := TObject(Obj2);
Pointer(Obj1) := nil;
Pointer(Obj2) := nil;
Temp1.Free;
Temp2.Free;
end;
यह इस तरह से ऊपर नमूना फिर से लिखने के लिए हमें की अनुमति देता है:
InitialiseNil(A, B);
try
A := TMyObject.Create;
B := TMyObject.Create;
A.DoSomething;
B.DoSomething;
finally
FreeAndNil(B, A);
end;
मैं एक बहुत ही इसी तरह उत्तर पोस्ट किया गया था, एक मामूली परिवर्तन डाल करने के लिए किया जाएगा 'newOrderSource: = TWebNewOrderSource.Create() ; कोशिश करने से पहले, और 'newOrderSource: = nil;' को हटा दें। –
यह भी काम करता है और एक अनियंत्रित असाइनमेंट को हटा देता है लेकिन मैंने इस मामले में सादगी और स्थिरता का पक्ष लिया क्योंकि यह असाइनमेंट को सहेजने की अत्यधिक संभावना नहीं है यदि डेटाबेस में "सामान" कॉल करने पर बहुत अंतर आएगा। – chuckj
मैं हर समय इसका उपयोग करता हूं लेकिन सुरक्षा के संबंध में, आपको ध्यान रखना चाहिए कि, ओपी के मूल कोड की तुलना में, यह आपको किसी एक कन्स्ट्रक्टर में उठाए गए अपवादों से बचाता है, लेकिन ** वस्तुओं को मुक्त करते समय उठाए गए अपवादों से ** ** नहीं। यदि आप इसके बारे में उलझन में हैं, तो आपका एकमात्र विकल्प है कि ऑब्जेक्ट्स के रूप में कई प्रयास करें/अंत में (या उन्हें इंटरफेस लागू करें और उन्हें दायरे से बाहर जाने दें)। –