यह भी याद रखें कि यदि आपका ब्लॉक किसी अन्य ऑब्जेक्ट को संदर्भित करता है, जो तब बरकरार रहता है तो चक्र को बनाए रखा जा सकता है self।
मुझे यकीन नहीं है कि कचरा संग्रह इन चक्रों को बनाए रखने में मदद कर सकता है। यदि ऑब्जेक्ट ब्लॉक (जिसे मैं सर्वर ऑब्जेक्ट कहूंगा) को आउटलाइव self(क्लाइंट ऑब्जेक्ट) कहूंगा , selfतो ब्लॉक के अंदर के संदर्भ को तब तक चक्रीय नहीं माना जाएगा जब तक कि रिटेनिंग ऑब्जेक्ट स्वयं जारी नहीं हो जाता। यदि सर्वर ऑब्जेक्ट अपने क्लाइंट को बहुत दूर करता है, तो आपके पास एक महत्वपूर्ण मेमोरी लीक हो सकती है।
चूंकि कोई साफ समाधान नहीं हैं, इसलिए मैं निम्नलिखित वर्कअराउंड की सिफारिश करूंगा। अपनी समस्या को ठीक करने के लिए उनमें से एक या अधिक का चयन करने के लिए स्वतंत्र महसूस करें।
- केवल पूर्ण होने के लिए ब्लॉक का उपयोग करें , और ओपन-एंडेड घटनाओं के लिए नहीं। उदाहरण के लिए, जैसे कि तरीकों के लिए ब्लॉक का उपयोग करें
doSomethingAndWhenDoneExecuteThisBlock:, न कि तरीकों की तरह setNotificationHandlerBlock:। पूर्णता के लिए उपयोग किए जाने वाले ब्लॉक में जीवन के निश्चित छोर हैं, और मूल्यांकन के बाद सर्वर ऑब्जेक्ट द्वारा जारी किया जाना चाहिए। यह बनाए रखने के चक्र को लंबे समय तक रहने से रोकता है, भले ही ऐसा होता हो।
- उस कमजोर-संदर्भ नृत्य का वर्णन करें।
- रिलीज़ होने से पहले अपनी ऑब्जेक्ट को साफ़ करने के लिए एक विधि प्रदान करें, जो सर्वर ऑब्जेक्ट से ऑब्जेक्ट को "डिस्कनेक्ट" करता है जो इसके संदर्भ को पकड़ सकता है; और ऑब्जेक्ट पर कॉल करने से पहले इस विधि को कॉल करें। हालांकि यह विधि पूरी तरह से ठीक है यदि आपकी वस्तु में केवल एक ग्राहक है (या कुछ संदर्भ में एक सिंगलटन है), लेकिन यदि यह कई क्लाइंट हैं तो टूट जाएगा। आप मूल रूप से यहां बनाए रखने-गिनती तंत्र को हरा रहे हैं;
deallocइसके बजाय कॉल करने के लिए समान है release।
यदि आप सर्वर ऑब्जेक्ट लिख रहे हैं, तो केवल पूर्ण होने के लिए ब्लॉक तर्क लें। कॉलबैक के लिए ब्लॉक तर्क स्वीकार न करें, जैसे कि setEventHandlerBlock:। इसके बजाय, क्लासिक प्रतिनिधि पैटर्न पर वापस जाएं: एक औपचारिक प्रोटोकॉल बनाएं, और एक setEventDelegate:विधि का विज्ञापन करें । प्रतिनिधि को न रखें। यदि आप एक औपचारिक प्रोटोकॉल भी नहीं बनाना चाहते हैं, तो एक चयनकर्ता को प्रतिनिधि कॉलबैक के रूप में स्वीकार करें।
और अंत में, इस पैटर्न को अलार्म बजना चाहिए:
- (शून्य) डीललोक {
[myServerObject रिलीज़CallbackBlocksForObject: स्व];
...
}
यदि आप उन ब्लॉक को हटाने का प्रयास कर रहे हैं जो selfअंदर से संदर्भित कर सकते हैं dealloc, तो आप पहले से ही परेशानी में हैं। deallocब्लॉक में संदर्भों के कारण बनाए रखने वाले चक्र के कारण कभी भी कॉल नहीं किया जा सकता है, जिसका अर्थ है कि आपकी वस्तु बस तब तक लीक होने वाली है जब तक कि सर्वर ऑब्जेक्ट को हटा नहीं दिया जाता है।
selfप्रॉक्सीthisसिर्फ चारों ओर फ्लिप बातें करने के लिए। जावास्क्रिप्ट में मैं अपनीthisक्लोजर कॉल करता हूंself, इसलिए यह अच्छा और संतुलित लगता है। :)