ओबीजे-सी संदेश कैसे प्रेषित किए जाते हैं?
उद्देश्य-सी संदेश रनटाइम के objc_msgSend()
फ़ंक्शन का उपयोग करके प्रेषित किए जाते हैं। [। संदेश पर तर्कों की एक चर सूची भेजी जा रही]
- प्राप्त वस्तु
- संदेश के चयनकर्ता
:
Apple docs में दिखाया गया है, समारोह कम से कम 2 तर्क लेता है
कक्षा के उदाहरणों में isa
पॉइंटर है, जो कि उनके क्लास ऑब्जेक्ट के लिए पॉइंटर है। प्रत्येक ऑब्जेक्ट में विधियों के चयनकर्ता वर्ग ऑब्जेक्ट में "टेबल" में संग्रहीत होते हैं, और objc_msgSend()
फ़ंक्शन क्लास ऑब्जेक्ट में isa
पॉइंटर का पालन करता है, इस तालिका को खोजने के लिए, और यह जांचता है कि विधि कक्षा के लिए तालिका में है या नहीं । यदि यह नहीं मिल रहा है, तो यह कक्षा के सुपरक्लास की तालिका में विधि की तलाश करता है। यदि नहीं मिला, तो यह ऑब्जेक्ट ट्री जारी रखता है, जब तक कि यह या तो विधि पाता है या रूट ऑब्जेक्ट (NSObject
) तक पहुंच जाता है। इस बिंदु पर, एक अपवाद फेंक दिया जाता है।
इंस्टेंस विधि पॉइंटर्स कैश कैसे होते हैं और क्या आप (सामान्य रूप से) कोड को पढ़कर बता सकते हैं कि कोई संदेश कैश किया जाएगा?
एप्पल के ऑब्जेक्टिव-सी क्रम गाइड से Messaging पर:
मैसेजिंग प्रक्रिया को गति देने, क्रम प्रणाली चयनकर्ताओं और तरीकों के पते कैश के रूप में वे उपयोग किया जाता है। प्रत्येक वर्ग के लिए एक अलग कैश है, और इसमें विरासत विधियों के साथ-साथ कक्षा में परिभाषित विधियों के लिए चयनकर्ता शामिल हो सकते हैं। प्रेषण तालिकाओं को खोजने से पहले, मैसेजिंग रूटीन पहले प्राप्त करने वाले ऑब्जेक्ट की कक्षा के कैश की जांच करता है (इस सिद्धांत पर कि एक विधि जिसका उपयोग एक बार किया जा सकता है) फिर से उपयोग किया जा सकता है)। यदि विधि चयनकर्ता कैश में है, तो मैसेजिंग फ़ंक्शन कॉल से थोड़ी धीमी है।एक बार एक कार्यक्रम अपने कैश को "गर्म करने" के लिए काफी देर तक चल रहा है, लगभग सभी संदेश भेजते हैं जो एक कैश विधि पाता है। कार्यक्रम चलने के रूप में नए संदेशों को समायोजित करने के लिए कैश गतिशील रूप से बढ़ते हैं।
जैसा कि कहा गया है, कार्यक्रम चलने के बाद कैशिंग शुरू हो जाती है, और कार्यक्रम के लंबे समय तक चलने के बाद, अधिकांश विधि कॉल कैश्ड विधि के माध्यम से चलेंगे। जैसा कि यह भी कहता है, कैशिंग होती है क्योंकि विधियों का उपयोग किया जाता है, इसलिए जब इसका उपयोग किया जाता है तो एक संदेश केवल कैश किया जाता है।
क्या क्लास विधियां अनिवार्य रूप से सी फ़ंक्शन (या सी ++ में स्थिर वर्ग विधि) जैसी हैं, या क्या उनके लिए कुछ और है?
कक्षा वस्तुओं कक्षाओं के उदाहरणों के समान तरीके से विधि प्रेषण संभालती है। प्रत्येक वर्ग ऑब्जेक्ट में एक ऑब्जेक्ट होता है जो नामक ऑब्जेक्ट में अपने वर्ग विधियों को संग्रहीत करता है। क्लास ऑब्जेक्ट का अपना isa
पॉइंटर है जो इसके मेटाक्लास ऑब्जेक्ट में है, जिसके बदले में सुपर मेटाक्लास ऑब्जेक्ट्स हैं, जो क्लास ऑब्जेक्ट्स को प्राप्त कर सकते हैं। वर्ग तरीकों की विधि प्रेषण के रूप में तो यह है:
- प्रेषण प्रणाली metaclass वस्तु
- metaclass वस्तु की विधि तालिका वर्ग विधि की खोज की है करने के लिए वर्ग वस्तु की
isa
सूचक इस प्रकार है।
- यदि नहीं मिला, तो खोज मेटाक्लास ऑब्जेक्ट के सुपरक्लास पर जारी है, जहां खोज जारी है।
- यह प्रक्रिया तब तक दोहराई जाती है जब तक कि विधि पाई जाती है, या जब तक यह रूट मेटाक्लास नहीं हो जाती है, और अपवाद फेंक दिया जाता है।
बहुत बढ़िया विवरण। मुझे लगता है कि गतिशील प्रेषण प्रणाली को समझना और चयनकर्ता कैसे शामिल हैं, यह भी बताते हैं कि विधि नाम अद्वितीय क्यों होना चाहिए, और उद्देश्य-सी जावा और सी ++ के समान तरीके से ओवरलोडेड विधियों का समर्थन नहीं करता है। चूंकि चयनकर्ता को पूर्णांक के रूप में कैश किया जाता है, उसी नाम वाला कोई भी विधि उसी चयनकर्ता को मैप करेगा। बेहतर या बदतर के लिए, यह प्रोग्राम्स को उचित तरीके से नामकरण विधियों के बारे में अधिक सोचने के लिए मजबूर करता है। –
यदि आप गहरे जाना चाहते हैं ... http://www.friday.com/bbum/2009/12/18/objc_msgsend-part-1-the-road-map/ – bbum
विशेष 'आगे' और ' performv 'तरीकों? उन्हें कब बुलाया जाता है? –