ऑब्जेक्टिव-सी नेमस्पेस टकराव को हल करने का सबसे अच्छा तरीका क्या है?


174

उद्देश्य-सी का कोई नामस्थान नहीं है; यह बहुत कुछ सी की तरह है, सब कुछ एक वैश्विक नाम स्थान के भीतर है। सामान्य अभ्यास प्रारंभिक कक्षाओं के साथ उपसर्ग करना है, उदाहरण के लिए यदि आप आईबीएम पर काम कर रहे हैं, तो आप उन्हें "आईबीएम" के साथ उपसर्ग कर सकते हैं; यदि आप Microsoft के लिए काम करते हैं, तो आप "MS" का उपयोग कर सकते हैं; और इसी तरह। कभी-कभी प्रारंभिक परियोजना का उल्लेख करते हैं, उदाहरण के लिए "एआई" के साथ एडियम उपसर्ग वर्ग (जैसा कि इसके पीछे कोई कंपनी नहीं है कि आप आद्याक्षर ले सकते हैं)। Apple NS के साथ कक्षाएं उपसर्ग करता है और कहता है कि यह उपसर्ग केवल Apple के लिए आरक्षित है।

अभी तक तो ठीक है। लेकिन सामने एक वर्ग के नाम के लिए 2 से 4 पत्र जोड़ना एक बहुत ही सीमित नाम स्थान है। उदाहरण के लिए, MS या AI एक पूरी तरह से अलग अर्थ हो सकता है (AI उदाहरण के लिए Artificial Intelligence हो सकता है) और कुछ अन्य डेवलपर उनका उपयोग करने और समान रूप से नामित वर्ग बनाने का निर्णय ले सकते हैं। बैंग , नेमस्पेस टक्कर।

ठीक है, अगर यह आपकी अपनी कक्षाओं में से एक और आपके द्वारा उपयोग किए जा रहे बाहरी ढांचे के बीच टकराव है, तो आप आसानी से अपनी कक्षा के नामकरण को बदल सकते हैं, कोई बड़ी बात नहीं। लेकिन क्या होगा यदि आप दो बाहरी फ्रेमवर्क का उपयोग करते हैं, दोनों फ्रेमवर्क जो आपके पास स्रोत नहीं हैं और जिन्हें आप बदल नहीं सकते हैं? आपका आवेदन उन दोनों के साथ लिंक करता है और आपको नाम संघर्ष मिलते हैं। आप इनका समाधान कैसे करेंगे? इस तरह से उनके आसपास काम करने का सबसे अच्छा तरीका क्या है कि आप अभी भी दोनों वर्गों का उपयोग कर सकते हैं?

C में आप लाइब्रेरी से सीधे लिंक न करके इनके चारों ओर काम कर सकते हैं, इसके बजाय आप dlopen () का उपयोग करके रनटाइम पर लाइब्रेरी को लोड करते हैं, फिर उस प्रतीक को ढूंढें जिसे आप dlsym () का उपयोग करके देख रहे हैं और इसे एक वैश्विक प्रतीक (जिसे आप असाइन करते हैं) अपनी पसंद के किसी भी तरीके को नाम दे सकते हैं) और फिर इस वैश्विक प्रतीक के माध्यम से एक्सेस कर सकते हैं। उदाहरण के लिए, यदि आपका कोई विरोध है, क्योंकि कुछ C लाइब्रेरी में ओपन () नाम का एक फंक्शन है, तो आप myOpen नाम के एक वेरिएबल को परिभाषित कर सकते हैं और यह लाइब्रेरी के ओपन () फंक्शन की ओर इशारा करता है, इस प्रकार जब आप सिस्टम ओपन () का उपयोग करना चाहते हैं , आप बस खुले का उपयोग करें () और जब आप दूसरे का उपयोग करना चाहते हैं, तो आप इसे myOpen पहचानकर्ता के माध्यम से एक्सेस करते हैं।

क्या ऑब्जेक्टिव-सी में कुछ ऐसा ही संभव है और यदि नहीं, तो क्या आप नाम-स्थान के टकराव के समाधान का उपयोग कर सकते हैं? कोई विचार?


अपडेट करें:

बस इसे स्पष्ट करने के लिए: उत्तर देने वाले सुझाव देते हैं कि अग्रिम में नेमस्पेस टकराव से कैसे बचा जाए या बेहतर नाम स्थान कैसे बनाएं, निश्चित रूप से स्वागत है; हालाँकि, मैं उन्हें उत्तर के रूप में स्वीकार नहीं करूंगा क्योंकि वे मेरी समस्या का समाधान नहीं करते हैं। मेरे पास दो पुस्तकालय हैं और उनके वर्ग के नाम टकराते हैं। मैं उन्हें बदल नहीं सकता; मेरे पास किसी एक का स्रोत नहीं है। टक्कर पहले से ही है और अग्रिम में कैसे बचा जा सकता है पर सुझाव अब मदद नहीं करेगा। मैं उन्हें इन चौखटे के डेवलपर्स के लिए अग्रेषित कर सकता हूं और आशा करता हूं कि वे भविष्य में एक बेहतर नाम स्थान का चयन करेंगे, लेकिन फिलहाल मैं एक ही आवेदन के भीतर चौखटे के साथ काम करने के लिए एक समाधान खोज रहा हूं। इसे संभव बनाने के लिए कोई उपाय?


7
आपके पास एक अच्छा सवाल है (अगर आपको दो चौखटे चाहिए, तो नाम की टक्कर क्या होगी) लेकिन यह पाठ में दफन है। इसे स्पष्ट करने के लिए संशोधित करें, और आप अभी जो आपके पास है जैसे सरल उत्तर से बचेंगे।
बेंजो

4
यह ऑब्जेक्टिव-सी लैंग्वेज के मौजूदा डिजाइन के साथ मेरा सबसे बड़ा ग्रिप है। नीचे दिए गए उत्तरों को देखें; जो वास्तव में सवाल (NSBundle अनलोडिंग, डीओ का उपयोग करते हुए, आदि) को संबोधित करते हैं, वे ऐसे घृणित हैक हैं, जो किसी नामस्थान संघर्ष से बचने के लिए तुच्छ के रूप में कुछ के लिए आवश्यक नहीं होना चाहिए।
इरिकप्रिस

@erikprice: आमीन। मैं obj-c सीख रहा हूं, और इस मुद्दे को हिट करता हूं। यहाँ एक सरल समाधान की तलाश में आया .... लंगड़ा।
डेव मेटेर

1
रिकॉर्ड के लिए, तकनीकी रूप से सी और ऑब्जेक्टिव-सी, कई नाम रिक्त स्थान के लिए समर्थन प्रदान करते हैं - ठीक वैसा नहीं, जैसा ओपी देख रहा है। ऑब्जेक्ट

हम्म, मुझे नहीं पता था कि। एक भयानक डिजाइन निर्णय की तरह नहीं?
निको

जवाबों:


47

यदि आपको एक ही समय में दोनों फ्रेमवर्क से कक्षाओं का उपयोग करने की आवश्यकता नहीं है, और आप उन प्लेटफार्मों को लक्षित कर रहे हैं जो NSBundle अनलोडिंग का समर्थन करते हैं (OS X 10.4 या बाद में, कोई GNUStep समर्थन नहीं), और प्रदर्शन वास्तव में आपके लिए कोई समस्या नहीं है, मेरा मानना ​​है कि जब आप किसी वर्ग को उससे उपयोग करने के लिए हर बार एक फ्रेमवर्क लोड कर सकते थे, और फिर उसे लोड कर सकते हैं और दूसरे को लोड कर सकते हैं जब आपको दूसरे फ्रेमवर्क का उपयोग करने की आवश्यकता होती है।

मेरा प्रारंभिक विचार NSBundle का उपयोग करके किसी एक फ्रेमवर्क को लोड करने के लिए किया गया था, फिर उस फ्रेमवर्क के अंदर की कक्षाओं को कॉपी या फिर नामांकित किया, और फिर दूसरे फ्रेमवर्क को लोड किया। इसके साथ दो मुश्किलें हैं। सबसे पहले, मैं एक क्लास का नाम बदलने या कॉपी करने के लिए बताए गए डेटा की प्रतिलिपि बनाने के लिए एक फ़ंक्शन नहीं ढूंढ सका, और उस पहले फ्रेमवर्क में किसी भी अन्य वर्ग का नाम जो संदर्भ वाले वर्ग का संदर्भ देता है, अब दूसरे फ्रेमवर्क से क्लास का संदर्भ देगा।

यदि किसी IMP द्वारा इंगित किए गए डेटा की प्रतिलिपि बनाने का कोई तरीका हो तो आपको किसी वर्ग की प्रतिलिपि बनाने या उसका नाम बदलने की आवश्यकता नहीं होगी। आप एक नया वर्ग बना सकते हैं और फिर ivars, विधियों, गुणों और श्रेणियों की नकल कर सकते हैं। बहुत अधिक काम, लेकिन यह संभव है। हालांकि, आपको अभी भी गलत वर्ग को संदर्भित करने वाली रूपरेखा में अन्य वर्गों के साथ एक समस्या होगी।

EDIT: C और ऑब्जेक्टिव-सी रनटाइम्स के बीच मूलभूत अंतर है, जैसा कि मैं इसे समझता हूं, जब पुस्तकालयों को लोड किया जाता है, तो उन पुस्तकालयों के कार्यों में उनके द्वारा संदर्भित किसी भी प्रतीक के संकेत होते हैं, जबकि ऑब्जेक्टिव-सी में, वे स्ट्रिंग का प्रतिनिधित्व करते हैं थसोई प्रतीकों के नाम। इस प्रकार, आपके उदाहरण में, आप प्रतीक के पते को स्मृति में प्राप्त करने और इसे दूसरे प्रतीक से संलग्न करने के लिए dlsym का उपयोग कर सकते हैं। लाइब्रेरी में अन्य कोड अभी भी काम करता है क्योंकि आप मूल प्रतीक का पता नहीं बदल रहे हैं। ऑब्जेक्टिव-सी, क्लास के नामों को एड्रेस करने के लिए लुकअप टेबल का उपयोग करता है, और यह 1-1 मैपिंग है, इसलिए आपके पास एक ही नाम के दो क्लास नहीं हो सकते। इस प्रकार, दोनों वर्गों को लोड करने के लिए, उनमें से एक को अपना नाम बदलना होगा। हालाँकि, जब अन्य वर्गों को उस नाम से किसी एक वर्ग तक पहुँचने की आवश्यकता होती है,


5
मेरा मानना ​​है कि बंडल अनलोडिंग 10.5 या उसके बाद तक असमर्थित था।
क्विन टेलर

93

एक अद्वितीय उपसर्ग के साथ अपनी कक्षाओं को फिर से बनाना मूल रूप से एकमात्र विकल्प है लेकिन इस कम खराब और बदसूरत बनाने के कई तरीके हैं। यहां विकल्पों की लंबी चर्चा है । मेरा पसंदीदा @compatibility_aliasउद्देश्य-सी संकलक निर्देश है ( यहां वर्णित है )। आप @compatibility_aliasएक वर्ग का नाम बदलने के लिए उपयोग कर सकते हैं , जिससे आप FQDN या इस तरह के कुछ उपसर्ग का उपयोग करके अपनी कक्षा का नाम रख सकते हैं :

@interface COM_WHATEVER_ClassName : NSObject
@end

@compatibility_alias ClassName COM_WHATEVER_ClassName
// now ClassName is an alias for COM_WHATEVER_ClassName

@implementation ClassName //OK
//blah
@end

ClassName *myClass; //OK

एक पूरी रणनीति के हिस्से के रूप में, आप अपने सभी वर्गों को एक अद्वितीय उपसर्ग जैसे कि FQDN के साथ उपसर्ग कर सकते हैं और फिर सभी के साथ एक हेडर बना @compatibility_aliasसकते हैं (मुझे लगता है कि आप ऑटो-हेडर कहा-उत्पन्न कर सकते हैं)।

इस तरह उपसर्ग करने का नकारात्मक पक्ष यह है कि आपको किसी COM_WHATEVER_ClassNameभी चीज़ में सही वर्ग नाम (जैसे ऊपर) दर्ज करना होगा जो संकलक के अलावा एक स्ट्रिंग से वर्ग नाम की आवश्यकता है। विशेष रूप से, @compatibility_aliasएक संकलक निर्देश है, एक रनटाइम फ़ंक्शन नहीं है इसलिए NSClassFromString(ClassName)विफल हो जाएगा (वापसी nil) - आपको उपयोग करना होगा NSClassFromString(COM_WHATERVER_ClassName)। आप ibtoolएक इंटरफ़ेस बिल्डर nib / xib में वर्ग नामों को संशोधित करने के लिए बिल्ड चरण के माध्यम से उपयोग कर सकते हैं ताकि आपको इंटरफ़ेस बिल्डर में पूर्ण COM_WHATEVER _... लिखना न पड़े।

अंतिम चेतावनी: क्योंकि यह एक संकलक निर्देश है (और उस पर एक अस्पष्ट), यह संकलक के पार पोर्टेबल नहीं हो सकता है। विशेष रूप से, मुझे नहीं पता कि यह एलएलवीएम परियोजना से क्लैंग फ्रंटेंड के साथ काम करता है, हालांकि इसे एलएलवीएम-जीसीसी (एलएलवीएम जीसीसी फ्रंटेंड का उपयोग करके) के साथ काम करना चाहिए।


4
संगतता_लियास के लिए अपवोट, मुझे उस बारे में नहीं पता था! धन्यवाद। लेकिन इससे मेरी समस्या हल नहीं होती। मैं किसी भी ढांचे के किसी भी उपसर्ग को बदलने के लिए नियंत्रण में नहीं हूं जिसका मैं उपयोग कर रहा हूं, मेरे पास केवल द्विआधारी रूप में है और वे टकराते हैं। मुझे उसके बारे में क्या करना चाहिए?
मिकी

किस फाइल (.h या .m) में @compatibility_alias लाइन जाना चाहिए?
एलेक्स बैसन

1
@Alex_Basson @compatibility_alias को शायद हेडर में जाना चाहिए ताकि यह जहाँ भी दिखाई दे, @interface घोषणा दिखाई दे।
बैरी वार्क

मुझे आश्चर्य है कि क्या आप प्रोटोकॉल नामों के साथ @compatibility_alias का उपयोग कर सकते हैं, या टाइपिडिफ परिभाषाएँ, या उस मामले के लिए कुछ और?
अली

यहाँ अच्छे विचार हैं। NSClassFromString (ClassName) को अलियास किए गए वर्गों के लिए शून्य से लौटने से रोकने के लिए विधि स्वीज़िंग का उपयोग किया जा सकता है? क्लास के नाम लेने वाले सभी तरीकों को खोजना शायद मुश्किल होगा।
डिक्की सिंह

12

कई लोगों ने पहले से ही कुछ मुश्किल और चालाक कोड साझा किए हैं जो समस्या को हल करने में मदद कर सकते हैं। सुझावों में से कुछ काम कर सकते हैं, लेकिन उनमें से सभी आदर्श से कम हैं, और उनमें से कुछ लागू करने के लिए नीच हैं। (कभी-कभी बदसूरत हैक्स अपरिहार्य होते हैं, लेकिन मैं जब भी उनसे बचने की कोशिश करता हूं।) एक व्यावहारिक दृष्टिकोण से, यहां मेरे सुझाव हैं।

  1. किसी भी मामले में, संघर्ष के दोनों ढांचे के डेवलपर्स को सूचित करें , और यह स्पष्ट करें कि इससे बचने और / या इससे निपटने में उनकी विफलता आपको वास्तविक व्यावसायिक समस्याएं पैदा कर रही है, जो कि अनसुलझे होने पर खोए हुए राजस्व राजस्व में बदल सकते हैं। इस बात पर जोर दें कि प्रति-वर्ग आधार पर मौजूदा संघर्षों को हल करते समय कम घुसपैठ ठीक है, उनके उपसर्ग को पूरी तरह से बदलना (या एक का उपयोग करना यदि वे वर्तमान में नहीं हैं, और उन पर शर्म करो!) यह सुनिश्चित करने का सबसे अच्छा तरीका है कि वे नहीं करेंगे फिर से वही समस्या देखें।
  2. यदि नामकरण संघर्ष कक्षाओं के एक छोटे से सेट तक सीमित है, तो देखें कि क्या आप सिर्फ उन वर्गों के आसपास काम कर सकते हैं, खासकर यदि परस्पर विरोधी वर्गों में से एक का उपयोग आपके कोड द्वारा, प्रत्यक्ष या अप्रत्यक्ष रूप से नहीं किया जा रहा है। यदि हां, तो देखें कि क्या विक्रेता फ्रेमवर्क का एक कस्टम संस्करण प्रदान करेगा जिसमें परस्पर विरोधी कक्षाएं शामिल नहीं हैं। यदि नहीं, तो इस तथ्य के बारे में स्पष्ट रहें कि उनकी अनम्यता आपके आरओआई को उनके ढांचे का उपयोग करने से कम कर रही है। कारण के भीतर pushy होने के बारे में बुरा मत सोचो - ग्राहक हमेशा सही होता है। ;-)
  3. यदि एक रूपरेखा अधिक "डिस्पेंसेबल" है, तो आप इसे दूसरे ढांचे (या कोड के संयोजन) के साथ बदलने पर विचार कर सकते हैं, या तो तृतीय-पक्ष या होमब्रे। (उत्तरार्द्ध अवांछनीय सबसे खराब स्थिति है, क्योंकि यह निश्चित रूप से विकास और रखरखाव दोनों के लिए अतिरिक्त व्यावसायिक लागतों को उकसाएगा।) यदि आप करते हैं, तो उस रूपरेखा के विक्रेता को सूचित करें कि आपने उनके ढांचे का उपयोग न करने का निर्णय क्यों लिया।
  4. यदि दोनों रूपरेखाओं को आपके आवेदन के लिए समान रूप से अपरिहार्य माना जाता है, तो एक या एक से अधिक अलग-अलग प्रक्रियाओं के लिए उनमें से एक के उपयोग के कारक का पता लगाएं, शायद डीओ के माध्यम से संवाद करना जैसा कि लुई जेरबार्ग ने सुझाव दिया था। संचार की डिग्री के आधार पर, यह उतना बुरा नहीं हो सकता जितना आप उम्मीद कर सकते हैं। तेंदुए में सीटबेल्ट सैंडबॉक्स प्रोफाइल का उपयोग करके प्रदान की गई अधिक बारीक सुरक्षा प्रदान करने के लिए कई प्रोग्राम (क्विकटाइम, मुझे विश्वास है) इस दृष्टिकोण का उपयोग करते हैं , जैसे कि आपके कोड के केवल एक विशिष्ट सबसेट को महत्वपूर्ण या संवेदनशील ऑपरेशन करने की अनुमति है। प्रदर्शन एक ट्रेडऑफ़ होगा, लेकिन आपका एकमात्र विकल्प हो सकता है

मैं अनुमान लगा रहा हूं कि लाइसेंस फीस, नियम और अवधि इनमें से किसी भी बिंदु पर त्वरित कार्रवाई को रोक सकती है। उम्मीद है कि आप संघर्ष को जल्द से जल्द हल कर पाएंगे। सौभाग्य!


8

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

अन्य संभावित समाधान भी हैं, लेकिन उनमें से बहुत कुछ सटीक स्थिति पर निर्भर करता है। विशेष रूप से, क्या आप आधुनिक या विरासत रनटाइम का उपयोग कर रहे हैं, क्या आप मोटे या एकल आर्किटेक्चर हैं, 32 या 64 बिट, आप किस ओएस को लक्षित कर रहे हैं, क्या आप गतिशील रूप से लिंकिंग, स्टेटिकली लिंकिंग कर रहे हैं, या आपके पास कोई विकल्प है, और यह संभावित है कुछ ऐसा करने के लिए ठीक है जिसे नए सॉफ़्टवेयर अपडेट के लिए रखरखाव की आवश्यकता हो सकती है।

यदि आप वास्तव में हताश हैं, तो आप क्या कर सकते हैं:

  1. पुस्तकालयों में से एक के खिलाफ सीधे लिंक नहीं
  2. ओब्जेक्ट रनटाइम रूटीन के एक वैकल्पिक संस्करण को लागू करें जो लोड समय पर नाम बदलता है ( objc4 प्रोजेक्ट को चेकआउट करें , आपको वास्तव में क्या करना है, यह ऊपर पूछे गए कई प्रश्नों पर निर्भर करता है, लेकिन यह संभव होना चाहिए कोई फर्क नहीं पड़ता कि उत्तर क्या हैं )।
  3. अपने नए कार्यान्वयन को इंजेक्ट करने के लिए mach_override जैसी किसी चीज़ का उपयोग करें
  4. नई लाइब्रेरी को सामान्य तरीकों का उपयोग करके लोड करें, यह पैच लिंक्ड रूटीन के माध्यम से जाएगा और इसका क्लासनेम बदल जाएगा

ऊपर बहुत श्रम गहन होने जा रहा है, और यदि आपको इसे कई आर्क और विभिन्न रनटाइम संस्करणों के खिलाफ लागू करने की आवश्यकता है, तो यह बहुत अप्रिय होगा, लेकिन यह निश्चित रूप से काम करने के लिए बनाया जा सकता है।


4

क्या आपने रनटाइम फ़ंक्शंस (/usr/include/objc/runtime.h) का उपयोग करके परस्पर विरोधी वर्गों में से एक को एक गैर-टकराए वर्ग के लिए क्लोन किया है, और फिर टकराते हुए क्लास फ्रेमवर्क को लोड किया है? (इससे काम करने के लिए अलग-अलग समय पर लोडिंग फ्रेमवर्क को लोड करना होगा।)

आप रनवे के साथ वर्गों आइवर, विधियों (नाम और कार्यान्वयन पते के साथ) और नामों का निरीक्षण कर सकते हैं, और अपने स्वयं के रूप में अच्छी तरह से गतिशील रूप से समान आइवर लेआउट, विधियों के नाम / कार्यान्वयन पते, और केवल नाम से अलग (नाम से बचने के लिए) बना सकते हैं। टक्कर)


3

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

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


लाइब्रेरी को डिस्क पर बदलना प्रश्न से बाहर है, क्योंकि लाइसेंस इसकी अनुमति नहीं देगा। प्रतीकों को स्मृति में बदलना संभव होगा, लेकिन मुझे कोई रास्ता नहीं दिख रहा है कि यह कैसे किया जा सकता है (मेमोरी के लिए काम को लोड करना, इसे संशोधित करना और फिर इसे डायनेमिक लिंकर में पास करना ... इसके लिए कोई विधि नहीं देखें)।
मेकी

3
ठीक है - यह तय करने का समय कि दोनों में से कौन सी लाइब्रेरी कम महत्वपूर्ण है, और एक प्रतिस्थापन खोजने के लिए। और जिसको आप भुगतान करते हैं उसे समझाइए लेकिन आप यह छोड़ रहे हैं कि आप जो कारण बदल रहे हैं वह इस टकराव के कारण है और वे आपकी समस्या को ठीक करके आपके व्यवसाय को बनाए रख सकते हैं।
जोनाथन लेफ़लर

2

@compatibility_alias वर्ग नामस्थान विरोधों को हल करने में सक्षम होगा, उदा

@compatibility_alias NewAliasClass OriginalClass;

हालाँकि, यह किसी भी एंम, टाइपफेड, या प्रोटोकॉल नेमस्पेस टकराव को हल नहीं करेगा । इसके अलावा, यह @classमूल वर्ग के आगे के पर्दों के साथ अच्छा नहीं खेलता है । चूँकि अधिकांश रूपरेखाएँ इन गैर-वर्गीय चीज़ों के साथ आएँगी, जैसे कि टाईपडेफ़्स, आप संभवतः संगतता के साथ नेमस्पेसिंग समस्या को ठीक नहीं कर पाएंगे।

मैंने आपकी एक समान समस्या को देखा , लेकिन मेरे पास स्रोत तक पहुंच थी और फ्रेमवर्क का निर्माण कर रहा था। इसके लिए मुझे जो सबसे अच्छा समाधान मिला, वह @compatibility_aliasशत्रु / टाइपफेड / प्रोटोकॉल / आदि का समर्थन करने के लिए #defines के साथ सशर्त रूप से उपयोग कर रहा था । आप यह हैडर में कंपाइलिंग यूनिट के लिए कर सकते हैं, जिसमें हैडर के लिए दूसरे कोलाइडिंग ढांचे में सामान के विस्तार के जोखिम को कम किया जा सकता है।


1

ऐसा लगता है कि मुद्दा यह है कि आप हेडर फ़ाइलों को एक ही अनुवाद इकाई (स्रोत फ़ाइल) में दोनों प्रणालियों से संदर्भित नहीं कर सकते। यदि आप पुस्तकालयों के आसपास ऑब्जेक्टिव-सी रैपर बनाते हैं (उन्हें प्रक्रिया में और अधिक प्रयोग करने योग्य बनाते हैं), और रैपर क्लासेस के कार्यान्वयन में प्रत्येक लाइब्रेरी के लिए केवल #include करें, तो यह प्रभावी रूप से नाम टकरावों को अलग करेगा।

मुझे इसका उद्देश्य- c (अभी शुरू होना) में पर्याप्त अनुभव नहीं है, लेकिन मेरा मानना ​​है कि मैं सी में क्या करूंगा।


1
लेकिन क्या आप तब भी टकराव में नहीं भागेंगे, यदि आपने दोनों रैपर हेडरों को एक ही फाइल में शामिल करने की कोशिश की हो (क्योंकि उन्हें प्रत्येक को अपने संबंधित ढांचे के हेडर को खुद शामिल करना होगा)?
विल्को

0

फाइलों को उपसर्ग करना सबसे सरल उपाय है, जिसके बारे में मैं जानता हूं। कोकादेव का एक नामस्थान पृष्ठ है जो नाम स्थान टकराव से बचने का सामुदायिक प्रयास है। इस सूची में खुद को जोड़ने के लिए स्वतंत्र महसूस करें, मेरा मानना ​​है कि यह वही है जो इसके लिए है।

http://www.cocoadev.com/index.pl?ChooseYourOwnPrefix


यदि फ़ाइलों के भीतर परिभाषित ऑब्जेक्ट समस्या का कारण बनता है, तो फ़ाइलों को उपसर्ग करना कैसे मदद करता है? मैं निश्चित रूप से h फ़ाइलों में हेरफेर कर सकता हूं, लेकिन तब लिंकर को ऑब्जेक्ट्स को फ्रेम के खिलाफ पसंद करने पर बिल्कुल भी नहीं मिलेगा: - /
Mecki

मेरा मानना ​​है कि यह प्रारंभिक समस्या के समाधान के बजाय सबसे बेहतर होगा।
अली

यह प्रश्न को बिल्कुल भी संबोधित नहीं करता है
Madbreaks

0

यदि आपके पास टक्कर है, तो मैं आपको सुझाव दूंगा कि आप अपने आवेदन में से किसी एक ढांचे को कैसे सुधार सकते हैं। एक टकराव होने से पता चलता है कि दोनों एक जैसी चीजें कर रहे हैं और यह संभव है कि आप एक अतिरिक्त फ्रेमवर्क का उपयोग करके बस अपने एप्लिकेशन को रिफ्लेक्ट कर सकते हैं। न केवल यह आपके नाम स्थान की समस्या को हल करेगा, बल्कि यह आपके कोड को अधिक मजबूत, बनाए रखने में आसान और अधिक कुशल बना देगा।

अधिक तकनीकी समाधान पर, यदि मैं आपकी स्थिति में हूं तो यह मेरी पसंद होगी।


0

यदि टकराव केवल स्थैतिक लिंक स्तर पर है, तो आप यह चुन सकते हैं कि प्रतीकों को हल करने के लिए किस लाइब्रेरी का उपयोग किया जाता है:

cc foo.o -ldog bar.o -lcat

यदि foo.oऔर bar.oदोनों प्रतीक का संदर्भ देते हैं ratतो libdogहल हो जाएगाfoo.o की ratऔर libcatसमाधान हो जाएगा bar.o'एस rat


0

बस एक विचार .. परीक्षण नहीं किया गया या सिद्ध नहीं किया गया और यह निशान का तरीका हो सकता है, लेकिन क्या आपने उस वर्ग के लिए एक एडेप्टर लिखने पर विचार किया है जो आप चौखटे के सरल से उपयोग करते हैं .. या कम से कम उनके इंटरफेस?

यदि आप चौखटे के सरल के चारों ओर एक आवरण लिखना चाहते थे (या जो आपके पास कम से कम पहुंच वाले इंटरफेस है) तो उस आवरण को पुस्तकालय में संकलित करना संभव नहीं होगा। यह देखते हुए कि पुस्तकालय पूर्वनिर्मित है और केवल इसके हेडर वितरित किए जाने की आवश्यकता है, आप प्रभावी रूप से अंतर्निहित रूपरेखा को छिपाएंगे और क्लैशिंग के साथ इसे दूसरे फ्रेमवर्क के साथ संयोजित करने के लिए स्वतंत्र होंगे।

मैं निश्चित रूप से इस बात की सराहना करता हूं कि ऐसे समय होने की संभावना है जब आपको एक ही समय में दोनों रूपरेखाओं से कक्षा का उपयोग करने की आवश्यकता होती है, लेकिन आप उस ढांचे के आगे के वर्ग एडेप्टर के लिए कारखाने प्रदान कर सकते हैं। उस बिंदु के पीछे मुझे लगता है कि आपको दोनों फ्रेमवर्क से उपयोग किए जाने वाले इंटरफेस को बाहर निकालने के लिए थोड़ी सी रिफैक्टिंग की आवश्यकता होगी, जो आपको अपना आवरण बनाने के लिए एक अच्छा शुरुआती बिंदु प्रदान करना चाहिए।

आप अपने अनुसार पुस्तकालय का निर्माण कर सकते हैं और जब आपको लिपटे हुए पुस्तकालय से और अधिक कार्यक्षमता की आवश्यकता होती है, और जब आप इसे बदलते हैं तो बस पुन: व्यवस्थित होते हैं।

फिर, किसी भी तरह से सिद्ध नहीं किया गया, लेकिन एक परिप्रेक्ष्य जोड़ने जैसा महसूस किया। आशा करता हूँ की ये काम करेगा :)


-1

यदि आपके पास दो फ्रेमवर्क हैं, जिनमें समान फ़ंक्शन नाम है, तो आप गतिशील रूप से फ़्रेमवर्क लोड करने का प्रयास कर सकते हैं। यह अयोग्य होगा, लेकिन संभव है। यह उद्देश्य-सी कक्षाओं के साथ कैसे किया जाता है, मुझे नहीं पता। मैं अनुमान लगा रहा हूं कि NSBundleकक्षा में वे विधियाँ होंगी जो एक विशिष्ट वर्ग को लोड करेंगी।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.