2012-05-17 5 views
5

क्या यह अनुमति है और क्यों?क्या इसे उद्देश्य सी में किसी ब्लॉक के हस्ताक्षर को 'परिवर्तन'/दुरुपयोग/ओवरराइड करने की अनुमति है?

void (^bar)(NSNumber *) = ^(NSNumber *number) { 
    NSLog(@"Value is %@, class is %@.", number, [number class]); 
}; 
bar([NSNumber numberWithInt:10]); 

void (^foo)(id) = bar; 
foo([NSDate date]); 

आउटपुट है:

Value is 10, class is __NSCFNumber. 
Value is 2012-05-17 18:54:14 +0000, class is __NSDate. 

मैं संबंधित कुछ भी है कि यह बताता है नहीं पा सके। क्या आप उद्देश्य सी ब्लॉक विनिर्देश के लिए एक लिंक प्रदान कर सकते हैं जिसमें यह शामिल है?

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

+0

आउटपुट _is_, या output_would be_? क्योंकि यदि आपने परीक्षण किया है और यह वास्तविक आउटपुट है, तो इसकी अनुमति है। – zneak

+1

एफवाईआई इसे * [covariance और contravariance] कहा जाता है (http://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29) *। –

+0

यदि आप इसे इस तरह इस्तेमाल करना चाहते हैं तो मैं शून्य (^ बार) (आईडी) का उपयोग करूंगा। – Cthutu

उत्तर

6

अंतर्निहित कारणों यह काम करता है का एक संयोजन है:

[1] ऑब्जेक्टिव-सी (और सी) दृढ़ता से संकलन समय पर नहीं लिखा है। जबकि संकलक को संकलक द्वारा उत्पादित किया जा सकता है, लेकिन आमतौर पर उन्हें (कभी-कभी असुरक्षित प्रकार) के द्वारा चुप किया जा सकता है। इस मामले में आपका असाइनमेंट अमान्य है क्योंकि आप एक ब्लॉक संदर्भ निर्दिष्ट कर रहे हैं जो इसे की घोषणा करता हैNSNumber * के साथ एक अन्य तर्क संदर्भ में संगत एक तर्क मान जो केवल घोषित करता है कि इसे id के साथ संगत तर्क मान की आवश्यकता है। यह असुरक्षित प्रकार है और कभी-कभी रनटाइम त्रुटियों का उत्पादन करेगा, नीचे देखें।

[2] उद्देश्य-सी रनटाइम संदेश गुजरना गतिशील है, यह संदेश के लिए लक्षित कोड कोड के रूप में निर्धारित किया जाता है। इसका मतलब यह है कि ब्लॉक में number के आपके सभी उपयोग NSNumber पर विशिष्ट नहीं हैं जब आप NSDate रनटाइम पर पास करते हैं तो उचित तरीके अभी भी गतिशील रूप से स्थित हैं।

void (^bar)(NSNumber *) = ^(NSNumber *number) 
{ 
    NSLog(@"Value is %@, class is %@, int value is %d.", number, [number class], [number intValue]); 
}; 

और आप क्रम त्रुटियों देखेंगे: हालांकि अपने bar लिए बदल जाते हैं।

[3] [NSNumber numberWithInt:10] और [NSDate date दोनों] प्रकार id, नहीं NSNumber * & NSDate * के मूल्यों वापस जाने के लिए के रूप में आप उम्मीद कर सकते घोषित कर रहे हैं।

bar([NSDate date]); 

और किसी भी चेतावनी के बिना ही परिणाम मिल ... एक और उदाहरण के रूप में करने पर विचार करें::

NSNumber *num = [NSNumber numberWithInt:3]; 
NSDate *date = num;   // produces a warning 
id erase = num;    // erase type info and do... 
date = erase;    // effectively the same assignment, no warning 

रास्ता लो यह आपको foo की जरूरत नहीं है, तो आप सिर्फ टाइप कर सकते हैं इसका मतलब है : उद्देश्य-सी एक प्रकार की सुरक्षित भाषा नहीं है, संकलक कई मामलों में आपको संभावित समस्याओं के बारे में चेतावनी देगा, लेकिन यह सभी मामलों में ऐसा नहीं करेगा।

+0

आपके महान स्पष्टीकरण के लिए धन्यवाद।इसका मतलब है, भले ही मेरे पास एक अवैध असाइनमेंट है [1], मैं किसी भी रनटाइम त्रुटियों में तब तक नहीं चलेगा जब तक कि मैं सुनिश्चित करता हूं कि [2] कि ब्लॉक के अंदर 'संख्या' के मेरे सभी उपयोग भी संभव हैं घुसपैठ वर्ग (इस मामले में एनएसडीएटी)। – Klaas

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