2012-10-15 21 views
8

कहते हैं कि हम इस ब्लॉक है:ऑब्जेक्टिव-सी ब्लॉक मापदंडों

int (^aBlock)(BOOL) = ^(BOOL param) { ... 

मेरे इस की वर्तमान समझ है: पहला int वापसी प्रकार है, (^aBlock)(BOOL) विधि का नाम और इसके पैरामीटर के प्रकार देता है, और = ^(BOOL param) ब्लॉक के अंदर पैरामीटर का नाम है ... प्लस पैरामीटर का प्रकार फिर से?

सिंटैक्स क्यों है कि हमें पैरामीटर प्रकार को दो बार सूचीबद्ध करना है? क्या दो प्रकार कभी अलग हो सकते हैं?

उत्तर

11

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

id thisBlock = ^id (id x, NSUInteger idx) { 
    NSLog(@"x = %@",x); 
    return x; 
}; 

id (^thatBlock)(id obj, NSUInteger index) = thisBlock; 

तथ्य यह है कि वे एक दूसरे साधन से स्वतंत्र हैं संभवतः अभिव्यक्ति के बाएं हाथ से दाएं हाथ से टाइपिंग जानकारी के किसी प्रकार का स्थानांतरण या विरासत प्रदान करने का प्रयास करने के लिए यह सही भी नहीं है। और हाँ, प्रकार अलग-अलग हो सकते हैं - इस कोड को संकलित करें और निष्पादित करें ठीक है:

id (^thatBlock)(NSArray *, NSDictionary *, NSString *) = ^id (id x, id y, id z) { 
    NSLog(@"x = %@",x); 
    return x; 
}; 

thatBlock(@[],@{},@""); 

आशा है कि इससे मदद मिलती है!

+0

हाँ, यह कमाल है, धन्यवाद। बस स्पष्ट करने के लिए, क्या आपका दूसरा कोड कोड टाइपिंग जानकारी (और इसलिए फहरा हुआ) के हस्तांतरण का एक उदाहरण है? – chm

+0

नहीं, मैं बस यह दिखा रहा हूं कि बाएं हाथ और दाएं हाथ के बीच के प्रकार अलग-अलग हो सकते हैं, और कोड संकलित और चलाएगा। जहां तक ​​मैं वास्तव में बता सकता हूं, रिटर्न प्रकारों के अलावा अन्य ब्लॉक के साथ बहुत से प्रकार की जांच नहीं कर रही है। टाइपिंग जानकारी का कोई हस्तांतरण नहीं है क्योंकि यह वास्तव में एक चीज नहीं है, मैंने वाक्यांश दिया कि थोड़ा अजीब, मैं यह कहने की कोशिश कर रहा था कि संकलक ने ऐसा कुछ करने की कोशिश की है, लेकिन यह आवश्यक नहीं होगा, क्योंकि वहां ब्लॉकों की कुछ पॉलिमॉर्फिक विशेषताएं जो इस तरह की सुविधा में हस्तक्षेप करती हैं। –

1

सिंटैक्स क्यों है कि हमें पैरामीटर प्रकार को दो बार सूचीबद्ध करना है?

ब्लॉक इस तरह से बनाया गया है, और इसलिए आप इसे इस तरह से कर सकते हैं:

int (^aBlock)(BOOL); 

aBlock = ^(BOOL param) { 
    ... 
}; 

यह सिर्फ पसंद करती है

- (int)aMethodWithParam:(BOOL)param; 

- (int)aMethodWithParam:(BOOL)param { 
    ... 
} 

दो प्रकार कभी अलग हो सकता है?

नहीं, और क्या अधिक है, प्रकार के आदेश में एक ही, यानी होना चाहिए:

int (^aBlock)(BOOL, NSString*) = ^(BOOL param, NSString *aString) { 
    ... 
}; 

और यहाँ ब्लॉक के लिए एक स्पष्ट आंकड़ा है:

Image

2

कोड आपके द्वारा दिया गया स्निपेट ब्लॉक घोषणा नहीं है: यह एक ब्लॉक घोषणा और एक ब्लॉक परिभाषा है। सबसे पहले, आप एक पहचानकर्ता aBlock नामित घोषित:

^(BOOL param) { ... 

इन दोनों पार्स और अलग से मूल्यांकन कर रहे हैं:

int (^aBlock)(BOOL) 

तो आप एक ब्लॉक परिभाषित करते हैं। चूंकि आप एक दूसरे को असाइन कर रहे हैं, इसलिए कंपाइलर यह सुनिश्चित करने के लिए एक प्रकार-चेक करता है कि बाईं ओर की अभिव्यक्ति (आपकी aBlock घोषणा) दाएं हाथ की ओर अभिव्यक्ति के समान प्रकार है (ब्लॉक परिभाषा) ।

तो, जवाब है, इन भागों को अलग से मूल्यांकन करने की आवश्यकता है। चूंकि ब्लॉक परिभाषा को स्वयं संकलित किया जा रहा है, इसलिए आपको param का प्रकार शामिल करना होगा, अन्यथा संकलक को यह नहीं पता होगा कि यह किस प्रकार होना चाहिए। (हाँ, आप इस मामले में एक अपवाद बना सकते हैं, और काम भर में देखने के लिए है, लेकिन अन्य सभी स्थानों सी भाषा में आप एक प्रकार पहली देकर एक पहचानकर्ता घोषित, तो क्यों इसे दूसरे तरीके से यहां करते हैं?)

लेकिन - आप कह सकते हैं - यदि यह सच है तो मुझे दाएं हाथ पर रिटर्न प्रकार (int) को परिभाषित क्यों नहीं किया गया है?

आप का बहुत अजीब। जवाब यह है कि, जब ब्लॉक अभिव्यक्ति लिखते हैं, तो आपको रिटर्न प्रकार को परिभाषित करने की आवश्यकता नहीं होती है, क्योंकि संकलक ब्लॉक के अंदर रिटर्न स्टेटमेंट (या इसकी कमी) से इसका अनुमान लगा सकता है।

(तो क्यों आप समारोह परिभाषा के साथ वापसी प्रकार में शामिल करना है? ठीक है, इतिहास, मुझे लगता है। प्रोग्रामिंग भाषा परिभाषाओं अपूर्ण मनुष्यों द्वारा बनाये गये थे।)

+0

"कोड आप दे दिया है छोटा सा अंश है नहीं एक ब्लॉक घोषणा" - बहुत सही! धन्यवाद, मैं इसे संपादित कर सकता हूं! – chm

-1

Ry's Objective C Tutorial के अनुसार:

ब्लाकों सामान्य कार्यों के रूप में सभी एक ही यांत्रिकी का उपयोग करें। आप एक ब्लॉक वैरिएबल घोषित कर सकते हैं जैसे कि आप एक फ़ंक्शन घोषित करेंगे।

NSInteger (^BlocksAddition)(NSInteger x,NSInteger y)=^NSInteger(NSInteger x, NSInteger y){ 

    return x+y; 
}; 

NSUInteger result=BlocksAddition(4,5); 
NSLog(@"Addition Result:%d",result); 
+0

जब आप किसी और के काम से टेक्स्ट कॉपी करते हैं, तो आपको यह कहने की ज़रूरत है कि टेक्स्ट कहां से आता है, और मूल स्रोत से वापस लिंक करें, और आपको उन शब्दों को सही ढंग से उद्धृत करने की भी आवश्यकता है * जो आपके नहीं हैं *। अन्यथा, ** आप चोरी चोरी कर रहे हैं **। अपने उत्तरों में * अन्य लोगों के काम * को उचित रूप से संदर्भित करने के तरीके के बारे में अतिरिक्त जानकारी के लिए, कृपया देखें [दूसरों द्वारा लिखित सामग्री का संदर्भ कैसे लें] (http://stackoverflow.com/help/referencing)। –

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

  • कोई संबंधित समस्या नहीं^_^