6

क्या कोई ऐसा मामला है जहां जानबूझकर विनाश को रोकने के लिए एक बनाए रखने चक्र बनाते हैं, फिर इसे बाद में साफ करना, समस्या का सबसे अच्छा समाधान है?प्रयोजनपूर्वक बनाए रखें चक्र (जीसी के बिना उद्देश्य सी)

यदि हां, तो कोको टच या नेक्स्टस्टेप ढांचे में इसका उदाहरण हैं?

मैं इस प्रश्न का उद्देश्य एआरसी के साथ उद्देश्य सी के लिए विशिष्ट होना चाहता हूं क्योंकि जीसी के साथ उद्देश्य सी या जीसी के साथ अन्य भाषाओं में अलग-अलग व्यवहार हो सकता है।

+0

एक बेहतर समाधान नहीं होगा एक ivar या अन्य उपयुक्त चर का उपयोग कर एक मजबूत संदर्भ रखने के लिए? – rmaddy

+0

सामान्य ज्ञान हाँ कहेंगे। लेकिन यही कारण है कि मैंने सवाल पूछा।शायद एक ऐसा मामला है जहां एक बनाए रखने चक्र (जैसे कि एक वस्तु स्वयं को बरकरार रखती है) बनाना सबसे अच्छा समाधान है। – MikeS

+1

यह उत्तर देने का एक कठिन सवाल है क्योंकि यह बहुत खुला है। "कभी" या "कभी नहीं" और "सर्वश्रेष्ठ" वाले प्रश्नों का उत्तर अच्छी तरह से नहीं दिया जा सकता है। यदि आपके पास पूछने के लिए ठोस उपयोग केस था तो यह बेहतर होगा। – rmaddy

उत्तर

7

निश्चित रूप से। यह वास्तव में असामान्य नहीं है, हालांकि आपको इसका एहसास नहीं हो सकता है।

उदाहरण के लिए, मान लें कि मेरा नियंत्रक नेटवर्क अनुरोध कर रहा है, और मैं वास्तव में यह सुनिश्चित करने की ज़रूरत है कि मैं प्रतिक्रिया को संभालता हूं, भले ही उपयोगकर्ता उस नियंत्रक से दूर हो गया हो।

मैं कुछ इस तरह कर सकते हैं:

- (void)doNetworkThing { 
    __block MyController *blockSelf = self; 

    NSURLRequest *request = // some request 
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler: 
     ^(NSURLResponse *response, NSData *data, NSError *error) { 
      // Handle the response here 
      [blockSelf doThingWithResponse:response]; 
     }]; 
} 

यह परिचय एक छोटी सी चक्र जहां self ही कारण बना हुआ है मजबूत सूचक blockSelf को ही बताए द्वारा बनाए रखे जाने की बरकरार रहती है। blockSelf तक दायरे से बाहर चला जाता है, स्वयं को हटाया नहीं जाएगा।

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

तो मूल रूप से, blockSelf एक अस्थायी बनाए रखने चक्र का कारण बन गया, जो यह सुनिश्चित करने में उपयोगी था कि अनुरोध समाप्त होने तक डेलोकेशन नहीं हो सका। क्योंकि एआरसी स्वचालित रूप से बनाए रखने की गणना को साफ़ करता है जब __block चर दायरे से बाहर हो जाता है, यह एक बनाए रखने चक्र की तरह नहीं दिखता है। लेकिन फिर भी, यही वह है।

+4

जबकि ब्लॉक-रिटेन-सेल्फ उदाहरण अच्छा है, आपको कभी भी व्यू कंट्रोलर के अंदर नेटवर्क एक्सेस नहीं करना चाहिए क्योंकि वे किसी भी समय दूर जा सकते हैं । आपको केवल मॉडल ऑब्जेक्ट्स (या मॉडल कंट्रोलर) में नेटवर्क एक्सेस करना चाहिए जिसमें लंबे जीवनकाल हों। परीक्षण करना और कई परेशान करने वाले कोने के मामलों से बचा जाना बहुत आसान है। –

+0

@BJHomer, अच्छा उदाहरण। मैंने इस परिदृश्य के बारे में सोचा नहीं था। मैं बस आगे बढ़ जाऊंगा और मेरी प्रतिक्रिया हटा दूंगा क्योंकि यह सिर्फ सादा गलत है। – aLevelOfIndirection

1

निश्चित रूप से, कई हैं। सबसे विशेष रूप से NSURLConnection यह सुनिश्चित करने के लिए कि प्रतिनिधि कनेक्शन पूरा होने से पहले दूर नहीं जा सकता है, अपने प्रतिनिधि के साथ एक बरकरार लूप उत्पन्न करता है। कुछ हद तक कम आदर्श, NSTimer अपने लक्ष्य के साथ एक बरकरार लूप उत्पन्न करता है। यह दुर्भाग्य से टाइमर को दोहराने के लिए समस्याएं पैदा करता है (इस समस्या को हल करने के कई प्रयासों में से एक के लिए RNTimer देखें)।

आम तौर पर, यदि प्रतिनिधिमंडल के प्रतिनिधि की तुलना में एक प्रतिनिधि वस्तु का बहुत कम जीवनकाल होता है, तो इसके लिए फायदेमंद बनाए रखने के लिए अपने प्रतिनिधि को बनाए रखना स्वाभाविक है।

यह कुछ कम आम है, लेकिन अभी भी कुछ प्रकार की वस्तुओं के लिए "स्वयं को बनाए रखने" के लिए किया जाता है। उदाहरण के लिए, यदि आपके पास कोई ऑब्जेक्ट था जिसे आप बनाना चाहते थे और कुछ ऑपरेशन करना चाहते थे, और फिर खुद को नष्ट कर देते हैं, तो स्वयं को बनाए रखना उस समस्या को हल कर सकता है। आम तौर पर इससे बचने के लिए बेहतर है और कॉलर ऑब्जेक्ट को बनाए रखने दें, लेकिन इसका अभी भी इसका उपयोग है (मैंने इसे लॉगिंग और अन्य गैर-महत्वपूर्ण संचालन के लिए उपयोग किया है जिसे मैं आग लगाना चाहता हूं)।

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

संबंधित मुद्दे