2013-01-22 15 views
7

मैं वर्तमान में Obj सी ब्लॉक के मूल सिद्धांतों और __block भंडारण प्रकार समझने में कोई परेशानी हो रही है। निम्नलिखित प्रलेखन से:समस्या आ रही है समझने ऑब्जेक्टिव-सी ब्लॉक प्रलेखन

http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/bxVariables.html#//apple_ref/doc/uid/TP40007502-CH6-SW6

मैं निम्नलिखित पैराग्राफ और उदाहरण समझने की कोशिश कर रहा हूँ:

जब एक ब्लॉक की नकल की है, यह मजबूत संदर्भ के भीतर इस्तेमाल चर आपत्ति उठाने बनाता है ब्लॉक। यदि आप एक विधि के क्रियान्वयन के भीतर एक ब्लॉक का उपयोग करते हैं:

आप संदर्भ द्वारा एक उदाहरण चर एक्सेस करते हैं, एक मजबूत संदर्भ आत्म करने के लिए किया जाता है; यदि आप मान द्वारा आवृत्ति चर का उपयोग करते हैं, तो चर के लिए एक मजबूत संदर्भ दिया जाता है। निम्न उदाहरण दो अलग-अलग स्थितियों को दर्शाते हैं:

dispatch_async(queue, ^{ 
    // instanceVariable is used by reference, a strong reference is made to self 
    doSomethingWithObject(instanceVariable); 
}); 

id localVariable = instanceVariable; 
dispatch_async(queue, ^{ 
    /* 
     localVariable is used by value, a strong reference is made to localVariable 
     (and not to self). 
    */ 
    doSomethingWithObject(localVariable); 
}); 

एक विशेष वस्तु चर के लिए इस व्यवहार को ओवरराइड करने के लिए आपको __block भंडारण प्रकार संशोधक के साथ यह चिह्नित कर सकते हैं।

मेरे सवालों का:

  1. वास्तव में किस प्रकार एक उदाहरण "संदर्भ द्वारा पहुँचा" है, जबकि अन्य एक चर द्वारा पहुँचा है? स्थानीय वैरिएबल "मूल्य से उपयोग क्यों किया जाता है?"
  2. "एक मजबूत संदर्भ स्वयं को बनाया गया है" का क्या मतलब है? यह किस "आत्म" का जिक्र कर रहा है?
  3. मैं दूसरे उदाहरण में localVariable को __block भंडारण प्रकार जोड़ते हैं, तो मुझे लगता है कि करने के लिए ब्लॉक चर पर बंद गलत हूँ, तो यह ढेर में चारों ओर रहता है जब तक ब्लॉक जारी किया गया है? क्या अन्य चीजें हो रही हैं?

धन्यवाद!

उत्तर

6

एक उदाहरण "संदर्भ द्वारा एक्सेस किया गया" वास्तव में एक उदाहरण है जबकि दूसरे को चर द्वारा एक्सेस किया जाता है? स्थानीय वैरिएबल "मूल्य से उपयोग क्यों किया जाता है?" इस को समझने के लिए

एक तरीका यह है निम्नलिखित:

  1. जब आप एक ब्लॉक विधि में परिभाषित में एक स्थानीय चर का उपयोग, क्या होता है कि चर की सामग्री के कुछ ब्लॉक में कॉपी किया जाता है है निजी मेमोरी, ताकि ब्लॉक उपलब्ध होने पर यह उपलब्ध हो (विधि बाहर निकलने के बाद); इस अर्थ में हम "मूल्य से" पहुंचने की बात कर सकते हैं (जैसा कि: मूल्य की प्रतिलिपि बनाई गई है); वाक्य रचनात्मक रूप से संकलक यह नहीं जानता कि localVariable की सामग्री का संदर्भ क्या है, इसलिए इसके मूल्यों को इस तरह माना जाता है;

  2. जब सीधे एक ब्लॉक एक वर्ग की एक विधि के भीतर परिभाषित में instanceVariable तक पहुँचने, संकलक जानता है कि हम एक ही उद्देश्य यह है कि विधि निष्पादित हो रहा है तक पहुँच रहे हैं और वहाँ कुछ भी कॉपी करने की जरूरत नहीं है, क्योंकि वस्तु एक लंबे समय तक है उस विधि से जीवन भर जहां ब्लॉक पाया जाता है; लेकिन हमें यह सुनिश्चित करने की ज़रूरत है कि जब ब्लॉक को निष्पादित किया जाता है तब वस्तु तब भी होती है, इसलिए हमें इसका एक मजबूत संदर्भ मिलता है।

अब, "संदर्भ द्वारा" का उपयोग करने के लिए के रूप में: पहले मामले में, आप संदर्भ की एक प्रति वर्ग के सदस्य के लिए मिलता है: यदि आप अपने मूल्य को बदल सकता है (लेकिन आप, नहीं कर सकते हैं क्योंकि संकलक इसे मना करता है), आप बस एक ब्लॉक निजी प्रति संशोधित कर रहे थे, इसलिए मूल वस्तु प्रभावित नहीं होती है।

दूसरे मामले में, आप instanceVariable का मूल्य संशोधित कर सकते हैं (जैसे: यह nil था और आप एक वस्तु के माध्यम से यह संदर्भित किया जाता आवंटित) और इस उद्देश्य यह है कि निष्पादित विधि थे ब्लॉक परिभाषित किया गया है को प्रभावित करेगा।

"एक मजबूत संदर्भ स्वयं को बनाया गया है" का क्या मतलब है? यह किस "आत्म" का जिक्र कर रहा है?

self वह ऑब्जेक्ट है जो वर्तमान में उस विधि को निष्पादित कर रहा है जहां ब्लॉक पाया जाता है। कि एक मजबूत संदर्भ केवल साधनों (एआरसी parlance में) बनाया जाता है कि वस्तु की रखरखाव गिनती बढ़ी है (यह सुनिश्चित करने के लिए कि कुछ अन्य इकाई इसे जारी करके इसे हटाया नहीं जा सकता है)।

मैं दूसरे उदाहरण में localVariable को __block भंडारण प्रकार जोड़ते हैं, तो मुझे लगता है कि करने के लिए ब्लॉक चर पर बंद गलत हूँ, तो यह ढेर में चारों ओर रहता है जब तक ब्लॉक जारी किया गया है? क्या अन्य चीजें हो रही हैं?

__block का उपयोग करके चर को हमेशा "संदर्भ द्वारा" एक्सेस किया जाता है, ताकि आप उन्हें संशोधित कर सकें।

यह है कि वे कैसे नियंत्रित किया जाता है है:

__block चर भंडारण कि चर का शाब्दिक दायरा और सभी ब्लॉक और ब्लॉक प्रतियां घोषित या चर का शाब्दिक दायरे के भीतर बनाया बीच साझा किया जाता में रहते हैं। इस प्रकार, भंडारण ढेर फ्रेम के विनाश से बच जाएगा यदि फ्रेम के भीतर घोषित ब्लॉक की कोई भी प्रति फ्रेम के अंत से परे जीवित रहती है (उदाहरण के लिए, बाद में निष्पादन के लिए कहीं भी लगाया जा रहा है)। दिए गए अक्षीय दायरे में एकाधिक ब्लॉक एक साथ साझा चर का उपयोग कर सकते हैं।

अनुकूलन के रूप में, ब्लॉक स्टोरेज स्टैक पर शुरू होता है-जैसे स्वयं ब्लॉक करते हैं। यदि ब्लॉक को ब्लॉक_copy (या उद्देश्य-सी में जब ब्लॉक को प्रतिलिपि भेजा जाता है) का उपयोग करके प्रतिलिपि बनाई जाती है, तो चर को ढेर में कॉपी किया जाता है। इस प्रकार, __block चर का पता समय के साथ बदल सकता है।

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