2011-06-17 11 views
5

किसी को कैसे इस ब्लॉक वाक्य रचना काम करता है व्याख्या कर सकते हैं?उद्देश्य-सी ब्लॉक वाक्यविन्यास - क्या कोई इसे समझा सकता है?

AStreamBuilder stream_builder = [ [ ^(void) 
    { 
     // some more code.. 
     return (NSInputStream *)[ NSInputStream inputStreamWithFileAtPath: some_path ]; 
    } copy ] autorelease ]; 
    return stream_builder; 

ब्लॉक का नाम क्या है? ब्लॉक की प्रतिलिपि क्यों बनाई जा रही है और फिर ऑटोरेलेटेड क्यों है? मैं इन सबसे छुटकारा यहाँ क्या हो रहा है .. ब्लॉक AStreamBuilder लौट लेकिन शरीर ब्लॉक के यह NSInputStream का एक उदाहरण देता है अंदर करने के लिए कहा जाता है के साथ भ्रमित कर रहा हूँ।

किसी को भी इस टूट कर सकते हैं?

उत्तर

9

यह ब्लॉक है:

^(void) 
    { 
     // some more code.. 
     return (NSInputStream *)[ NSInputStream inputStreamWithFileAtPath: some_path ]; 
    } 

यह किसी भी पैरामीटर प्राप्त नहीं होता है (इसलिए (void)) है और यह NSInputStream का एक उदाहरण देता है। ध्यान दें कि यह एक 'नाम' नहीं है - एक ही अर्थ है कि, उदाहरण के लिए: या तो

[[NSNumber alloc] initWithInt:42]; 

एक 'नाम' नहीं है।

चूंकि ब्लॉक को स्टैक पर बनाया गया है, यदि आपको ब्लॉक को वापस करने की आवश्यकता है तो आपको इसे ढेर से ढेर में कॉपी करना होगा (इसलिए -copy)। यह एक स्वामित्व वाली वस्तु है; आदेश में एक उद्देश्य यह है कि फोन करने वाले के स्वामित्व में नहीं है वापस जाने के लिए में, ब्लॉक autoreleased है (इसलिए -autorelease):

[ [ ^(void) 
    { 
     // some more code.. 
     return (NSInputStream *)[ NSInputStream inputStreamWithFileAtPath: some_path ]; 
    } copy ] autorelease ]; 

तो अंश के ऊपर एक autoreleased ब्लॉक कि ढेर करने के लिए ढेर से नकल किया गया है। यह एक चर

AStreamBuilder stream_builder = … 

को सौंपा गया है तो यह संभव है कि AStreamBuilder एक ब्लॉक है कि कोई पैरामीटर प्राप्त करता है और वापसी प्रकार NSInputStream (या एक प्रकार है कि के साथ संगत) है के लिए एक typedef है। ध्यान दें कि AStreamBuilder ब्लॉक द्वारा लौटाए गए मान के प्रकार के विपरीत एक ब्लॉक प्रकार है। की तरह कुछ:

typedef NSInputStream * (^AStreamBuilder)(void); 
0

ब्लॉक ढेर करने के लिए ढेर से इसे स्थानांतरित करने की नकल की जा रही है। यह आवश्यक है यदि आप उस क्षेत्र के बाहर ब्लॉक का उपयोग करना चाहते हैं जहां आप इसे बनाते हैं।

4

क्या ब्लॉक यहाँ के नाम है?

नया ब्लॉक परिवर्तनीय stream_builder को असाइन किया गया है। इसका नाम प्रति नाम नहीं है क्योंकि एक ब्लॉक "anonymous inline collection of code"

ब्लॉक की प्रतिलिपि क्यों बनाई जा रही है और फिर ऑटोरेलेटेड क्यों है?

क्योंकि यह वर्तमान दायरे के बाद चारों ओर रखा जा रहा है (इसे विधि/कार्य से वापस किया जा रहा है)। इसलिए इसे copied to the heap होना चाहिए।

ब्लॉक AStreamBuilder वापस जाने के लिए कहा जाता है, लेकिन ब्लॉक के शरीर के अंदर यह NSInputStream का एक उदाहरण देता

समारोह/विधि आप (एक है कि return stream_builder; साथ समाप्त होता है) में मौजूद हैं देता है एक AStreamBuilder (= नव निर्मित ब्लॉक)। भविष्य में कुछ बिंदु पर ब्लॉक पर invoked लौटाएगा।

+0

यदि ब्लॉक एनएसएसटी स्ट्रीम का एक उदाहरण वापस करने जा रहा है, तो उपरोक्त वाक्यविन्यास में वापसी प्रकार कैसे घोषित नहीं किया गया था? – randombits

+1

ऐसा इसलिए है क्योंकि 'शून्य' आप देखते हैं कि वापसी मूल्य नहीं है, लेकिन तर्क (ओं) है। इस ब्लॉक में कोई तर्क नहीं है। वापसी प्रकार यहां बिल्कुल निर्दिष्ट नहीं है। यह ठीक है क्योंकि "[वापसी का प्रकार वैकल्पिक है और वापसी विवरणों से अनुमानित है।] (Http://clang.llvm.org/docs/BlockLanguageSpec.txt)" – puzzle

+0

@rand वहां दो चीजें हो रही हैं: पर एक हाथ, पहेली के रूप में कहा, वापसी प्रकार वापसी बयान से अनुमानित है। दूसरी तरफ, 'एस्ट्रीमबिल्डर' एक 'टाइपपीफ' है जो ब्लॉक के रिटर्न प्रकार को परिभाषित करता है। कार्य करने के लिए असाइनमेंट के लिए, अनुमानित वापसी प्रकार को 'ASTreamBuilder' में परिभाषित रिटर्न प्रकार से मेल खाना चाहिए। आप Xcode में 'ASTreamBuilder' की घोषणा को राइट-क्लिक करके और परिभाषा पर कूदने का चयन कर सकते हैं। –

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