2011-10-26 31 views
36

मुझे पता है कि जब हम एक अज्ञात मान वस्तु बनाना चाहते हैं तो हम आईडी का उपयोग करते हैं। हालांकि, मुझे उत्सुकता है कि ऐप्पल ने आईडी का चयन क्यों किया जो रनटाइम के दौरान इसका मूल्य तय करता है, जब प्रत्येक ऑब्जेक्ट NSObject का उप-वर्ग होता है। तो id delegate के बजाय हम NSObject *delegate का उपयोग कर सकते थे क्या किसी को पता है क्यों? धन्यवाद।आईडी का उपयोग क्यों करें जब हम केवल NSObject का उपयोग कर सकते हैं?

+1

एनएसपीरोक्सी एक और मूल वर्ग है जो कोको आपूर्ति करता है। –

+0

एनएसओब्जेक्ट में आईएसए पॉइंटर होता है, आईडी नहीं है। Http://stackoverflow.com/a/19634973/944634 –

+0

पर क्या देखें? आईडी एक आईएसए सूचक है। http://stackoverflow.com/questions/1990695/in-cocoa-how-is-the-id-type-defined – TheAmateurProgrammer

उत्तर

39

id इस प्रकार को मिटा देता है और यह कहने के बराबर है "यह वस्तु अनुवाद के लिए दृश्यमान किसी भी चयनकर्ता को प्रतिक्रिया देती है"। बेशक, आपकी ज़िम्मेदारी यह सुनिश्चित करने के लिए है कि जब आप प्रकार मिटाते हैं तो आपका प्रोग्राम सही होता है (और जब आप उन्हें टाइप करते हैं)।

हैं प्रकार NSObject थे, तो संकलक कहते थे, "NSObject चयनकर्ता का जवाब नहीं हो सकता है" चयनकर्ता NSObject के इंटरफ़ेस या प्रोटोकॉल यह गोद ले में घोषित नहीं किया गया। उस घटना में, आप इसे टाइप करने के लिए टाइप करने के लिए एक टाइपकास्ट भी जोड़ सकते हैं।

सख्त/सही प्रकार के साथ, कंपाइलर लात मार सकता है और आपकी मदद कर सकता है, जो बहुत अच्छा है क्योंकि ओबीजेसी एक बहुत ही गतिशील भाषा है।

id संग्रह प्रकारों (या भवन) का उपयोग करते समय विशेष रूप से उपयोगी होता है। ऑब्जेक्ट जोड़ना कोई समस्या नहीं होगी जबतक कि आपने एक नया रूट प्रकार परिभाषित नहीं किया है (NSObject से प्राप्त नहीं होता है)। संग्रह से मूल्य प्राप्त करने के लिए एक टाइपकास्ट की आवश्यकता होगी यदि हम इसे अपने बेस क्लास (NSObject) के अलावा किसी अन्य चीज़ के रूप में उपयोग करना चाहते थे।

उद्देश्य-सी जेनिक्स का समर्थन नहीं करता है - उदाहरण के लिए, NSString एस की घोषणा नहीं कर सकता है। आप NSArray को NSString एस के साथ पॉप्युलेट कर सकते हैं और id के माध्यम से इसे अधिक प्राकृतिक लिखित शैली के लिए पास कर सकते हैं जब सुरक्षा सुरक्षा संरक्षित नहीं होती है (ला जेनिक्स)।

तो, चलो कुछ वास्तविक कोड के साथ इस पर विस्तार करें।

उदाहरण A

NSString * string = [array objectAtIndex:0]; // << trust me (via id) 
return [string length]; 
-or- 
return [[array objectAtIndex:0] length]; // << trust me (via id) 

उदाहरण B

और अब मान लीजिए कि id उपलब्ध नहीं है और हम अपने सभी संकलक चेतावनी को ठीक है क्योंकि यह करने के लिए सही बात है करते हैं:

NSString * string = (NSString*)[array objectAtIndex:0]; // << typecast == trust me 
return [string length]; 
-or- 
return [(NSString*)[array objectAtIndex:0] length]; // << typecast == trust me 

id निर्णय नहीं लेता रनटाइम पर इसका मूल्य, न ही किसी भी NSObject करते हैं। ओबीजेसी ऑब्जेक्ट्स अंतर्निहित प्रचार नहीं करते हैं, उन्होंने औपचारिक पदोन्नति के बिना पॉइंटर डाला।

अपने उदाहरण के लिए संबंधित, मैं वास्तव में मेरी प्रतिनिधियों और मानकों NSObjects के रूप में प्रोटोकॉल के साथ की घोषणा:

NSObject<MONShapeDelegate>* delegate; 
+0

यह मेरे द्वारा उपयोग किए जाने वाले अन्य कंपाइलरों में भिन्न हो सकता है, लेकिन जहां तक ​​मुझे पता है, अगर आप घोषित करते हैं NSObject के रूप में एक प्रकार, संकलक मान लेगा कि ऑब्जेक्ट कुछ प्रोटोकॉल के सभी तरीकों को लागू करता है, यहां तक ​​कि वैकल्पिक भी। – Aberrant

+0

@Aberrant अगर कोई प्रतिनिधि विधि वैकल्पिक है, तो ऑब्जेक्ट को चयनकर्ता को जवाब देने के लिए यह * कॉलर * पर निर्भर करता है। – justin

+0

मुझे पता है, यही कारण है कि मैंने कहा कि संकलक मानता है कि वे लागू किए गए हैं। यदि ऐसा नहीं होता है, तो विकल्प हमेशा चेतावनियां पैदा करेंगे, क्योंकि संकलक यह सुनिश्चित नहीं कर सकता कि ऑब्जेक्ट रनटाइम पर जवाब देंगे या नहीं। – Aberrant

2

हर वस्तु सही नहीं है यही कारण है कि NSObject

का एक उपवर्ग है। आप एक वस्तु बना सकते हैं जो मूल वर्ग के रूप में कुछ भी नहीं है।

शायद यही कारण है कि आईडी पेश की गई थी।

11

हर वस्तु NSObject

का एक उपवर्ग एक गलत बयान है यही कारण है। आप उन वस्तुओं को बना सकते हैं जो NSObject से प्राप्त नहीं होते हैं। यह वास्तव में अनुशंसित नहीं है, लेकिन यह संभव है।

NSProxy एक उदाहरण है - यह NSObject से प्राप्त नहीं होता है।

+3

यह सिर्फ मेरे उत्तर का एक क्लोन है! –

+1

क्षमा करें:/जब मैंने कोई जवाब नहीं दिया था, तो मैंने इसे लिखा था, आपने मुझे पंच पर हराया ... कोई कठोर भावना नहीं है और वास्तव में नीचे वोट के लिए कोई ज़रूरत नहीं है ... इसके अलावा, आपने 'NSProxy' का उल्लेख नहीं किया है ... – Jasarien

+1

यदि यह एक स्टैक है और नीचे यह जवाब है तो @ जसारीन ने पहले जवाब दिया;) – beryllium

3
typedef struct objc_object { 
    Class isa; 
} *id; 

उद्देश्य-सी भाषा में id की वास्तविक परिभाषा है। उद्देश्य-सी रनटाइम सिस्टम id और Class के आसपास बनाया गया है। NSObject या सामान्य सुपर क्लास के साथ कुछ भी नहीं करना है।

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocObjectsClasses.html#//apple_ref/doc/uid/TP30001163-CH11-SW3

NSObject वर्ग

NSObject एक सुपर क्लास नहीं है एक रूट वर्ग है, और इसलिए। यह को उद्देश्य-सी ऑब्जेक्ट्स और ऑब्जेक्ट इंटरैक्शन के लिए मूल रूपरेखा परिभाषित करता है। यह कक्षाओं और कक्षाओं के उदाहरणों को प्रदान करता है जो से प्राप्त होते हैं, यह वस्तुओं के रूप में व्यवहार करने और रनटाइम सिस्टम के साथ सहयोग करने की क्षमता प्रदान करता है।

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

मुझे लगता है, इस वजह से यह मूल रूप से C नहीं C++ (या अन्य अधिक सख्त टाइपिंग भाषाओं) है।

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