objective c - Why [object doSomething] and not [*object doSomething]? -


उद्देश्य-सी में, क्यों [object doSomething] ? क्या यह नहीं होगा [* वस्तु doSomething] क्योंकि आप ऑब्जेक्ट पर एक विधि को बुला रहे हैं ?, जिसका मतलब है कि आपको पॉइन्डर को डीरेफर करना चाहिए?

उत्तर उद्देश्य सी की सी जड़ों को वापस harkens उद्देश्य-सी मूल रूप से सी के लिए कंपाइलर प्री-प्रोसेसर के रूप में लिखे गए थे। यह है, उद्देश्य-सी इतना संकलित नहीं किया गया था क्योंकि इसे सीधे सी में बदल दिया गया था और फिर संकलित किया गया था।

की परिभाषा के साथ शुरू करो प्रकार आईडी । इसे घोषित किया गया है:

  टाइपिंगफ़ाइल संरचना objc_object {class isa; } * आईडी;  

यही है, एक id एक संरचना के लिए एक सूचक है, जिसका पहला फ़ील्ड टाइप क्लास (जो, स्वयं, एक संरचना के लिए एक सूचक है जो कि कक्षा)। अब, NSObject पर विचार करें:

  @ इंटरफेस NSObject & lt; NSObject & gt; {कक्षा आईसा; }  

ध्यान दें कि NSObject का लेआउट और id द्वारा इंगित किए गए प्रकार का लेआउट समान हैं। इसका कारण यह है कि, वास्तव में, उद्देश्य-सी ऑब्जेक्ट का एक उदाहरण वास्तव में एक संरचना के लिए एक सूचक है, जिसका पहला फ़ील्ड - हमेशा एक पॉइंटर - क्लास को इंगित करता है जिसमें उस उदाहरण के तरीकों (कुछ अन्य मेटाडाटा के साथ )।

जब आप NSObject subclass और कुछ उदाहरण चर जोड़ने के लिए आप सभी intents और प्रयोजनों के लिए हैं, बस एक नई सी संरचना है कि आपके आवृत्ति चर स्लॉट्स उदाहरण के लिए स्लॉट्स पर concatenated के रूप में स्लॉट के रूप में शामिल सभी सुपर क्लासेस के लिए चर (आधुनिक क्रम समय काम करता है थोड़ा इसलिए कि एक सुपर वर्ग में सभी उपवर्गों को पुनः कंपाइल किए जाने की आवश्यकता के बिना जोड़ा गया इवार हो सकता है)।

अब, इन दो चर के बीच अंतर पर विचार करें:

<पूर्व> NSRect foo; एनएसआरएक्ट * बार;

(एनएसआरएक्ट एक साधारण सी संरचना है - कोई ओबीजेसी शामिल नहीं है)। फ़ू स्टैक पर भंडारण के साथ बनाया गया है स्टैक फ़्रेम बंद होने के बाद यह बच नहीं पाएगा, लेकिन आपको किसी भी मेमोरी को मुक्त करने की आवश्यकता नहीं है। बार एक एनएसआरएक्चर संरचना का एक संदर्भ है जो सबसे अधिक संभावना है, malloc ()

का उपयोग करके ढेर पर बनाया गया है यदि आप कहने की कोशिश करते हैं:

<पूर्व> NSArray foo; NSArray * बार;

कंपाइलर पहले के बारे में शिकायत करेगा, स्टैक आधारित ऑब्जेक्ट की पंक्तियों के साथ कुछ उद्देश्य- C में अनुमति नहीं है दूसरे शब्दों में, सभी उद्देश्य-सी वस्तुओं को ढेर से आवंटित किया जाना चाहिए (अधिक या कम - एक या दो अपवाद हैं, लेकिन वे इस चर्चा के लिए तुलनात्मक रूप से गूढ़ हैं) और परिणामस्वरूप, आप हमेशा ढेर पर कहा वस्तु के पते के माध्यम से एक ऑब्जेक्ट को देखें; आप हमेशा ऑब्जेक्ट्स के साथ पॉइंटर्स के साथ काम कर रहे हैं (और id टाइप वास्तव में केवल किसी भी पुराने ऑब्जेक्ट के लिए एक पॉइंटर है।)

भाषा की सी प्रीप्रोसेसर जड़ों पर वापस लौटना, आप प्रत्येक विधि कॉल को सी की एक समान पंक्ति में अनुवाद कर सकते हैं। उदाहरण के लिए, कोड की निम्न दो पंक्ति समान हैं:

  [myArray objectAtIndex: 42]; Objc_msgSend (myArray, @selector (objectAtIndex :), 42);  

इसी तरह, एक विधि इस तरह की घोषणा की:

  - (आईडी) objectAtIndex: (NSUInteger) a;  

सी फ़ंक्शन के समकक्ष इस तरह घोषित किया जाता है:

  id object_at_index (id स्व, SEL _cmd, NSUInteger a);  

और, objc_msgSend () को देखकर, पहली तर्क को id की तरह घोषित किया जाता है:

  ओबीजेसी_एक्सपोर्ट आईडी objc_msgseend (आईडी स्व, एसईएल ओप, ...);  

और इसी कारण से आप विधि कोड कॉल के लक्ष्य के रूप में * foo का उपयोग नहीं करते हैं उपरोक्त रूपों के माध्यम से अनुवाद करें - कॉल करने के लिए [myArray objectAtIndex: 42] उपरोक्त सी फ़ंक्शन कॉल में अनुवाद किया जाता है, जिसे बाद में समकक्ष C फ़ंक्शन कॉल घोषणा (सभी में तैयार किया गया है) विधि वाक्यविन्यास)।

ऑब्जेक्ट संदर्भ के माध्यम से किया जाता है क्योंकि यह मैसेंजर- objc_msgSend () को विधि तक कार्यान्वित करने के लिए कक्षा तक पहुंच देता है - साथ ही उस संदर्भ को पहले पैरामीटर बनने के लिए - - स्वयं का तरीका - जो अंततः निष्पादित होता है।

यदि आप वास्तव में गहरे जाना चाहते हैं, तो लेकिन जब तक आप पूरी तरह से परेशान नहीं हो जाते तब तक चिंता न करें।


Comments

Popular posts from this blog

sql - dynamically varied number of conditions in the 'where' statement using LINQ -

asp.net mvc - Dynamically Generated Ajax.BeginForm -

Debug on symbian -