2012-06-18 15 views
10

एप्पल से इस तकनीकी क्यू & एक के बारे में :http://developer.apple.com/library/mac/#qa/qa1490/_index.htmlस्थिर पुस्तकालयों में श्रेणियों को जोड़ने के लिए -ओबीजेसी लिंकर ध्वज की आवश्यकता क्यों है? (LLVM)

मुझे लगता है कि संकलक संकलन समय पर श्रेणियों में परिभाषित तरीकों के लिए कॉल को चिह्नित कर सकता है (यह जानता है कि वे एक वर्ग में नहीं परिभाषित किया गया और मुख्य वर्ग क्योंकि प्रोटोटाइप @interface Class (Category) सेक्शन में था) - इसलिए यह "बाहरी श्रेणी विधियों" की ऑब्जेक्ट फ़ाइलों में एक तालिका बना सकता है। फिर लिंकर, अपनी सामान्य लिंकिंग करने के बाद, सभी ऑब्जेक्ट्स से "बाहरी श्रेणी विधियों" तालिकाओं को संयोजित/विलय और संसाधित करने में सक्षम होना चाहिए और सभी लिंक किए गए ढांचे/पुस्तकालयों/वस्तुओं से मेल खाने वाले वर्ग श्रेणियों में मिलान करने वाले प्रतीकों की तलाश करना चाहिए, फिर यह उन लोगों को खींच सकते हैं जो लक्ष्य में पहले से नहीं थे।

मुझे कुछ याद आना चाहिए, लेकिन यह क्या है? यह क्यों संभव नहीं है?

उत्तर

14

लिंकर यादृच्छिक टुकड़ों के बड़े पुराने संग्रह की तरह स्थिर पुस्तकालयों का इलाज करता है, जिससे यह शेष लिंक इकाई से किसी भी प्रतीक अनुरोध को पूरा करने के लिए अलग-अलग टुकड़े खींच लेगा।

आईई। यदि मुख्य कार्यक्रम _foo कॉल और _foo केवल स्थिर पुस्तकालय, तो _foo में प्रकट होता है, किसी भी निर्भर प्रतीकों के साथ साथ, में घसीटा जाएगा।

हालांकि, जब आप एक वर्ग में एक विधि कॉल, वहाँ कोई विशिष्ट प्रतीक संदर्भ है उद्देश्य-सी की गतिशीलता के कारण।

-ObjC ध्वज लिंकर को बताता है कि, इस वजह से, इसे स्थिर पुस्तकालय से सभी श्रेणियों को पकड़ना चाहिए और इसे मुख्य बाइनरी में छोड़ देना चाहिए।


यह थोड़ा भ्रामक है और इस धारणा है कि संकलक इस बारे में होशियार (और, विश्वासपूर्वक, यह देव उपकरण स्तर पर सहायता देना चाहिए) होना चाहिए। कुछ चीजों को याद रखना महत्वपूर्ण है:

  • हेडर फ़ाइल में घोषित कुछ भी लिंकर के चारों ओर घूमने के समय काफी खो गया है। प्रतीक संकलन इकाइयों द्वारा बनाए जाते हैं, हेडर फ़ाइलों द्वारा नहीं। शीर्षलेख फ़ाइलें बहुत अधिक वादा उत्पन्न करती हैं कि एक प्रतीक को बाद में बनाया जाएगा या लिंक द्वारा पूरा किया जाएगा, लेकिन स्वयं में और स्वयं का प्रतीक नहीं बना सकता है (या अन्य सभी संकलन इकाई - प्रत्येक .o - की एक प्रति के साथ समाप्त हो जाएगा प्रतीक समय और प्रतीकता लिंक समय पर आ जाएगा)।

  • उद्देश्य-सी पूरी तरह गतिशील है। जब आप [(id)foo bar]; कहते हैं, तो केवल आवश्यकता है कि bar को पहले परिभाषित किया गया है। कोई फर्क नहीं पड़ता कि यह वास्तव में बिल्कुल लागू किया गया है (वैसे भी रनटाइम तक)।

  • श्रेणियाँ संबंधित @ अनुपूरक नहीं होना चाहिए; एक श्रेणी का उपयोग यह घोषित करने के लिए किया जा सकता है कि विधियां मौजूद हो सकती हैं और वास्तव में, @optional से @protocol जोड़ने से पहले, NSObject (ewwwwww) पर @implementation के साथ किसी भी श्रेणी का उपयोग करना आम था "अरे, यह वैकल्पिक विधि रनटाइम पर मौजूद हो सकती है "।

  • संकलन और लिंकिंग पूरी तरह से अलग प्रक्रियाएं हैं। संकलन कोड को विस्तारित करने और निष्पादन योग्य बाइट्स के पुस्तकालयों में बदलने के बारे में है। लिंकिंग उन पुस्तकालयों को लेने और उन्हें उन चीज़ों में एक साथ रखने के बारे में है जो वास्तव में चल सकते हैं, पुस्तकालयों के बीच सभी निर्भरताओं को हल करने सहित।कंपाइलर वास्तव में इस बारे में नहीं जानता कि कुछ कैसे जोड़ा जा सकता है और लिंकर के पास ऐसी कोई जानकारी नहीं है जहां चीजें (जो हार्ड प्रतीक उत्पन्न नहीं करती) को परिभाषित किया गया हो।

अंतिम परिणाम?

लिंकर में निर्भरताओं को हल करने के लिए पर्याप्त जानकारी नहीं है।

+0

लेकिन संकलक जानता है कि उसने एक श्रेणी में परिभाषित एक विधि को कॉल किया है, इसलिए यह लिंक समय पर उपयोग किए जाने के लिए एक विशिष्ट प्रतीक संदर्भ बना सकता है - यही मेरा प्रश्न है। मैं इसे तकनीकी क्यू एंड ए से जुड़े पहले से वर्णित की तुलना में थोड़ा गहराई से समझना चाहता हूं। – jhabbott

+0

ग्रेट उत्तर - एक प्रश्न। एक स्थिर lib से प्रतीक को जोड़ने के लिए अनुपालन करने के लिए पर्याप्त क्या है। बस '# import' या केवल एक चर 'MyClass c;' को परिभाषित करना, या क्या आपको अपनी कक्षा '[c myMethod]' पर एक विधि कॉल करना है? इस बारे में क्या है कि क्लास का इंटरफ़ेस बिल्डर में संदर्भित किया गया है? – Robert

+1

@ रॉबर्ट लिंकर को पुस्तकालय के साथ कड़ी लिंकिंग द्वारा हल किए गए प्रतीक को देखने की आवश्यकता है। यदि यह रनटाइम पर गतिशील रूप से हल किया गया प्रतीक है, तो यह गिनती नहीं करेगा (जैसे आईबी)। यह जरूरी नहीं है कि एक विधि कॉल हो, लेकिन यह उपयोग करने का सबसे आसान तंत्र है। अर्थात। '[MyClass वर्ग]; ', उदाहरण के लिए। – bbum

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