2011-10-13 12 views
6

पर विचार करें निम्नलिखित कोड टुकड़ा:ब्लाकों, लूप और स्थानीय चर

for(/* some condition */) { 
    int x = rand(); 
    [array addObject:^(){ 
     NSLog(@"%d", x); 
    }] 
} 

for(void (^block)() in array) { 
    block(); 
} 

अब मुझे लगता है कि पाश के लिए में एक्स करने के लिए आवंटित सभी मूल्यों को मुद्रित करने के लिए इस कोड स्निपेट उम्मीद होती है; हालांकि ऐसा लगता है कि सभी ब्लॉक एक ही 'एक्स' चर (संभवतः अंतिम एक) साझा करते हैं।

कोई विचार यह क्यों है और मैं ब्लॉक को कैसे परिभाषित कर सकता था क्योंकि प्रत्येक ब्लॉक में चर 'x' होता है क्योंकि ब्लॉक को परिभाषित किया गया था?

+0

मैं अभी भी खुद को ब्लॉक सीख रहा हूं लेकिन यहां एक अजीब चीज दिमाग में आती है। जब आप addObject करते हैं:, सरणी डिफ़ॉल्ट रूप से ब्लॉक ऑब्जेक्ट को बनाए रखेगी। हालांकि, ब्लॉक ऑब्जेक्ट्स को स्टैक पर रखा जाता है जब उन्हें घोषित किया जाता है, तो ऐसा लगता है कि वे तुरंत दायरे से बाहर हो जाएंगे। ब्लॉक_Copy ब्लॉक को ढेर में ले जायेगा जो सही काम करने जैसा लगता है। –

उत्तर

7

प्रलेखन विशेष रूप से says not to do this। इसका कारण यह है कि ब्लॉक को स्टैक पर आवंटित किया गया है, जिसका अर्थ है कि वे दायरे से बाहर जा सकते हैं। इसी कारण से आप पहले for लूप के बाहर परिवर्तनीय x तक नहीं पहुंच सकते हैं, आपको उस ब्लॉक का भी उपयोग नहीं करना चाहिए। x ब्लॉक के साथ-साथ दायरे से बाहर हो गया है, और इसमें कोई मूल्य हो सकता है।

इस के आसपास पाने के लिए आपको इतना तरह ब्लॉक की एक प्रति ले सकते हैं:

for(/* some condition */) { 
    int x = rand(); 
    void(^logBlock)() = ^() { NSLog(@"%d", x); } 
    [array addObject:[[logBlock copy] autorelease]]; 
} 

यह ढेर पर ब्लॉक चलता है, और आपकी समस्या का समाधान करना चाहिए।

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