2012-11-19 16 views
6

मैं एक सामान्य रूप में एक बहुत ही सामान्य स्थिति को दूर करने जा रहा हूं। मान लें कि मैं कुछ लाइब्रेरी ऑब्जेक्ट का निर्माण कर रहा हूं जो बंद हो जाता है, कुछ एसिंक काम करता है, फिर इसे पूरा होने पर एक प्रतिनिधि विधि पर वापस कॉल करता है। अब, कुछ मनमाना कारणों के लिए भी कहें कि मैं कॉलबैक के लिए एआरसी या ब्लॉक का उपयोग नहीं कर सकता। यह पुराना है। आइए इस ऑब्जेक्ट को वर्कर को कॉल करें।प्रतिनिधिमंडल ऑब्जेक्ट लाइफस्पेन्स को प्रतिनिधि कॉलबैक की अवधि के लिए कैसे बढ़ाया जाना चाहिए?

अब कहें कि विभिन्न ऐप्स में कई अन्य कक्षाएं हैं जो अपने सार्वजनिक इंटरफ़ेस से अलग वर्कर के बारे में कुछ भी नहीं जानते हैं। वे श्रमिकों को अपने स्वयं के सिरों पर उपयोग करते हैं। चलो उपभोक्ताओं को इन वर्गों को बुलाओ।

कहो कार्यकर्ता बनाता प्रतिनिधि इस तरह कॉलबैक:

// "Private" method called internally when work is done. 
- (void)somethingFinished 
{ 
    [self.delegate workerDidFinish]; 
    [self someTask]; 
} 

और कहते हैं कि कुछ विशेष उपभोक्ता इस तरह कॉलबैक संभालता है:

- (void)workerDidFinish 
{ 
    // Assume "worker" is a retain property to a Worker 
    // instance that we previously created and began working, 
    // and that it's also the sender of the message. 
    self.worker = nil; 
    // Other code... 
} 

अब, अगर और कुछ नहीं बनाए रखा गया है कि विशेष रूप से कार्यकर्ता उदाहरण के लिए, हम परेशानी में फिर से श्रमिक को हटा दिया जाएगा, फिर नियंत्रण -somethingFinished विधि पर वापस आ जाएगा, जहां यह -someTask को पुनः दावा या कचरा स्मृति, और संभावित रूप से क्रैश करने के लिए भेज देगा। किसी ने भी किसी भी स्मृति प्रबंधन नियमों का उल्लंघन नहीं किया है।

मैं यहां तकनीकी समाधान नहीं मांग रहा हूं। मुझे कई विकल्प पता हैं। मैं सोच रहा हूं कि फिक्स के लिए जिम्मेदारी का बोझ गिरता है। क्या मैं घटक डिजाइनर के रूप में, वर्कर की -somethingFinished विधि को कार्यान्वित कर सकता हूं जैसे कि कार्यकर्ता की उम्र [[self retain] autorelease] की शुरुआत में विधि की अवधि के लिए बढ़ा दी गई हो? या मुझे, घटक के उपभोक्ता के रूप में पता होना चाहिए कि मैं एक उदाहरण विधि के माध्यम से आधे रास्ते को दूर कर सकता हूं, और बाद में इसे रिलीज़ करने तक प्रतीक्षा कर सकता हूं?

This question के सभी उत्तर यह इंगित करते हैं कि कॉलबैक से ऑब्जेक्ट को जारी करना एक बुरा विचार है। दुर्भाग्यवश, उस प्रश्न में बहुत विचलित जानकारी है कि वर्कर (इस उदाहरण में CLLocationManager) को उस प्रतिनिधि को पास किया गया है जिसे मैंने जानबूझकर यहां से बचाया है। This question एक ही परिदृश्य से पीड़ित है, और अन्य समाधान प्रदान करता है।

व्यक्तिगत रूप से, मैं नहीं देख सकता कि उपभोक्ता को जिम्मेदार कैसे ठहराया जा सकता है। यह किसी भी मेमोरी प्रबंधन नियमों को तोड़ नहीं रहा है, और विनम्रता से श्रमिक के सार्वजनिक इंटरफेस का उपभोग कर रहा है। यह केवल एक उदाहरण जारी कर रहा है जब इसकी आवश्यकता नहीं है। लेकिन दूसरी तरफ, क्या इसका मतलब यह है कि किसी भी वस्तु को संभवतः, किसी भी तरह से मिड-विधि की जरूरतों को नष्ट कर दिया जा सकता है ताकि कृत्रिम रूप से अपनी उम्र बढ़ाई जा सके? प्रतिनिधि विधियां, आखिरकार, एकमात्र तरीका नहीं है कि एक संदेश प्रेषक किसी विधि के बीच में विघटित हो सकता है।

तो आखिरकार, फिक्स के लिए कौन जिम्मेदार है? कार्यकर्ता? उपभोक्ता? क्या यह कैननिक रूप से निर्धारित किया जा सकता है?

उत्तर

0

जब प्रतिनिधि को अधिसूचित किया जाता है, तो कार्यकर्ता को देखना शुरू कर देना चाहिए और इसे केवल तब रिलीज़ करना चाहिए जब कुछ फ़िनशिप विधि समाप्त हो जाती है।

+0

प्रतिनिधि पहले ही प्रतिनिधिमंडल का पर्यवेक्षक है। –

1

मुझे लगता है कि बोझ इस उदाहरण में श्रमिक पर है। समस्या यह है कि वर्कर ऑब्जेक्ट अपने उपभोक्ता को यह बताने के बाद आंतरिक रूप से कुछ कर रहा है कि उसका काम समाप्त हो गया है। उपभोक्ता केवल उपभोक्ता के लिए मौजूद है, इसलिए यदि उपभोक्ता का उद्देश्य पूरा हो गया है तो कर्मचारी अभी भी ऐसा कुछ क्यों कर रहा है जिसका उपभोक्ता के लिए कोई मूल्य नहीं है? यदि 'खपत योग्य' काम करने के बाद आंतरिक कार्यों को पूरा करने की आवश्यकता है तो उन कार्यों को श्रमिक वस्तु के उदाहरण में उचित रूप से नहीं रखा जाता है, लेकिन शायद कम अस्थिर पुस्तकालय वर्ग के स्वामित्व वाली किसी अन्य आंतरिक वस्तु द्वारा किया जाना चाहिए उपभोक्ता के कार्यों से हटा नहीं दिया जाएगा।

+0

मुझे नहीं लगता कि यह एक खिंचाव है कि किसी ऑब्जेक्ट को कॉल करने वाले किसी ऑब्जेक्ट के पास आंतरिक आंतरिक कॉल करने का कारण हो सकता है। वे क्लीनअप दिनचर्या के रूप में सरल हो सकता है। आप कह रहे हैं कि यह मामला नहीं होना चाहिए? –

+0

हां यह एक खिंचाव नहीं है लेकिन स्मृति प्रबंधन परिदृश्य दिया गया है, मैं प्रस्तावित कर रहा हूं कि यह उन वस्तुओं को क्लीनअप/आंतरिक कार्यों को छोड़ने के लिए एक बेहतर पैटर्न हो सकता है जो उपभोक्ता और रन लूप के विनाश के अधीन नहीं हैं। – foggzilla