2010-01-16 17 views
8

ठीक है, मुझे एक एहसास है कि आप जल्दी से यह इंगित करने में सक्षम होंगे कि मैं इस बारे में इतना उलझन में क्यों हूं, लेकिन मेरे पास एक सवाल है कि निम्नलिखित में संकलक क्यों नहीं होता त्रुटि या चेतावनी:उद्देश्य-सी प्रकार अनुमान

NSString * intValue = [ NSString stringWithFormat:@"int = %i", [ [ self.selectedObject valueForKey:name ] integerValue ] ]; 

selectedObject एक NSObject है, और name प्रकार int के @property का नाम एक ही है।

मुझे क्या perplexes क्यों संकलक पूरी तरह से ग्रहण करने के लिए कि [ self.selectedObject valueForKey:name ] की वापसी परिणाम प्रकार NSNumber * की है क्रम में करने के लिए श्रृंखला integerValue के लिए एक कॉल के साथ संदेश (यह typecasting के बिना) तैयार है।

जाहिर है, KVC NSNumber में गैर वस्तु "संख्या" प्रकार के लपेटता है, लेकिन वहाँ के लिए संकलक पता चला है कि -valueForKey: इस विशेष मामले में एक NSNumber * वापस आ जाएगी कोई रास्ता नहीं है।

"id" के साथ एक कंपाइलर चेतावनी में इसका परिणाम क्यों नहीं है, -integerValue 'का जवाब नहीं दे सकता है?

उत्तर

10

मुझे आशा है कि मुझे यह सही लगेगा: ऐसा इसलिए है क्योंकि id "विशेष" है। id प्रकार के ऑब्जेक्ट्स को आप जिस संदेश को चाहते हैं उसे भेजा जा सकता है, कंपाइलर द्वारा कोई जांच नहीं की जा रही है और सब कुछ रनटाइम में चेक किया जाएगा। या, दूसरे शब्दों में, id प्रकार उद्देश्य-सी का "गतिशील टाइपिंग" भाग है, जबकि अन्य सभी प्रकार (जैसे NSObject) "स्थैतिक टाइपिंग" भाग हैं।

इस तरह आप चुन सकते हैं कि आप स्थिर टाइपिंग का उपयोग करना चाहते हैं, और जहां आप डायनामिक टाइपिंग का उपयोग करना चाहते हैं। यह इस तरह से कुछ करने के लिए पूरी तरह से कानूनी है:

id str1 = @"Hello"; 
id str2 = [str1 stringByAppendingString:@", world"]; 

लेकिन आम तौर पर आप "कसकर" तार टाइप NSString रों के रूप में है, क्योंकि आप संकलन समय स्थिर प्रकार की जांच की सुविधा प्राप्त है, और केवल गतिशील टाइपिंग जहां का सहारा valueForKey स्थिति में, जैसे स्थिर व्यक्ति रास्ते में आ जाएगा।

+0

धन्यवाद! मुझे लगता था कि उद्देश्य आईडी में एक विशेषाधिकार प्राप्त प्रकार होने के साथ उसे 'आईडी' करना था। :) मेरी प्रवृत्ति हमेशा जब भी संभव हो चीजों को कसकर टाइप करना है, तो मुझे लगता है कि मुझे कभी भी इस अजीब व्यवहार का सामना नहीं हुआ। मान लीजिए कि 'आईडी' दोनों शक्तिशाली और खतरनाक बनाता है। मुझे आश्चर्य है कि 'आईडी' से निपटने के दौरान कंपाइलर को कुछ संदर्भ देने के लिए टाइपकास्ट करना बेहतर होता है, या अगर आप इसे छोड़ने के लिए बिल्कुल ठीक हैं तो क्या आप सकारात्मक हैं कि 'आईडी' क्या होगा (जैसा कि मेरे उदाहरण में मामला था) । – LucasTizma

+0

अंगूठे का नियम यह है: "स्टेटिक टाइपिंग जहां संभव हो, गतिशील टाइपिंग की आवश्यकता होती है।" (आप Google को और जानकारी प्राप्त करने के लिए कर सकते हैं।) इस मामले में मैं टाइपकास्ट नहीं करूंगा, यह केवल अभिव्यक्ति को पढ़ने के लिए कठिन बना देगा। कभी-कभी आपको कंपाइलर को सही विधि चुनने में मदद करने के लिए टाइपकास्ट करना होता है - http://stackoverflow.com/questions/1113270 देखें। – zoul

+0

लिंक के लिए धन्यवाद। विधि नामकरण के परिणामस्वरूप मुझे कुछ गंदे छोटे बग का सामना करना पड़ा है जो मौजूदा एसडीके विधि नामों के साथ "संघर्ष" होता है। सोचा कि संकलक मुझ पर पागल हो रहा था। :) और हाँ, मैं "स्टेटिक टाइपिंग जहां संभव हो, गतिशील टाइपिंग की आवश्यकता होने पर" दर्शन का पूरी तरह से समर्थक हूं। अब अगर केवल उद्देश्य-सी टाइप किए गए संग्रह के लिए समर्थन जोड़ देगा ... अपेक्षाकृत अधिक बार, मुझे पता है कि मेरे संग्रह स्टोर करने जा रहे हैं। – LucasTizma