जबकि मुझे लगता है कि मैं आपके प्रश्न का उत्तर दे सकता हूं, यह ऐसा उत्तर नहीं है जिसे आप पसंद करेंगे।
TL; DR: @objc
फ़ंक्शंस वर्तमान में प्रोटोकॉल एक्सटेंशन में नहीं हो सकते हैं। आप इसके बजाय एक आधार वर्ग बना सकते हैं, हालांकि यह एक आदर्श समाधान नहीं है।
प्रोटोकॉल एक्सटेंशन और ऑब्जेक्टिव-सी
सबसे पहले, यह प्रश्न / उत्तर ( ऑब्जेक्टिव-सी में एक्सेस किए गए प्रोटोकॉल पर एक्सटेंशन्स पर परिभाषित स्विफ्ट मेथड डिफाइन हो सकता है ) सुझाव देता है कि जिस तरह से प्रोटोकॉल एक्सटेंशन को हुड के तहत भेजा जाता है, प्रोटोकॉल एक्सटेंशन में घोषित तरीके objc_msgSend()
फ़ंक्शन के लिए दिखाई नहीं देते हैं , और इसलिए Objective-C कोड के लिए दृश्यमान नहीं हैं। चूँकि जिस विधि को आप अपने विस्तार में परिभाषित करने की कोशिश कर रहे हैं, उसे ऑब्जेक्टिव-सी (इसलिए UIKit
इसका उपयोग कर सकते हैं) के लिए दृश्यमान होना चाहिए , यह आपको शामिल नहीं करने के लिए चिल्लाता है @objc
, लेकिन एक बार जब आप इसे शामिल करते हैं, तो यह आपको चिल्लाता है क्योंकि @objc
इसमें अनुमति नहीं है प्रोटोकॉल एक्सटेंशन। यह शायद इसलिए है क्योंकि प्रोटोकॉल एक्सटेंशन वर्तमान में ऑब्जेक्टिव-सी के लिए दृश्यमान नहीं हैं।
हम यह भी देख सकते हैं कि त्रुटि संदेश एक बार हम कहते हैं @objc
कि "@objc का उपयोग केवल कक्षाओं के सदस्यों, @objc प्रोटोकॉल और कक्षाओं के ठोस एक्सटेंशन के साथ किया जा सकता है।" यह कोई वर्ग नहीं है; एक @objc प्रोटोकॉल का विस्तार प्रोटोकॉल परिभाषा में होने के कारण ही नहीं है (यानी आवश्यकताओं में), और शब्द "कंक्रीट" यह सुझाव देगा कि एक प्रोटोकॉल एक्सटेंशन एक ठोस वर्ग एक्सटेंशन के रूप में नहीं गिना जाता है।
वैकल्पिक हल
दुर्भाग्य से, यह बहुत अधिक पूरी तरह से आपको प्रोटोकॉल एक्सटेंशन का उपयोग करने से रोकता है, जब डिफ़ॉल्ट कार्यान्वयन ऑब्जेक्टिव-सी फ्रेमवर्क को दिखाई देना चाहिए। सबसे पहले, मुझे लगा कि शायद @objc
आपके प्रोटोकॉल एक्सटेंशन में अनुमति नहीं थी क्योंकि स्विफ्ट कंपाइलर गारंटी नहीं दे सकता था कि अनुरूप प्रकार वर्ग होंगे (भले ही आपने विशेष रूप से निर्दिष्ट किया हो UIViewController
)। इसलिए मैंने एक class
आवश्यकता रखी P1
। यह काम नहीं किया।
शायद केवल वर्कअराउंड यहां प्रोटोकॉल के बजाय बस बेस क्लास का उपयोग करना है, लेकिन यह स्पष्ट रूप से पूरी तरह से आदर्श नहीं है क्योंकि एक वर्ग में केवल एक ही आधार वर्ग हो सकता है लेकिन कई प्रोटोकॉल के अनुरूप है।
यदि आप इस मार्ग पर जाने का विकल्प चुनते हैं, तो कृपया इस प्रश्न ( स्विफ्ट 3 ओबीजीसी ऑप्शनल प्रोटोकॉल मेथड नॉट कॉल इन सबक्लास ) को ध्यान में रखें। ऐसा प्रतीत होता है कि स्विफ्ट 3 में एक और मौजूदा मुद्दा यह है कि उप-वर्ग अपने सुपरक्लास के वैकल्पिक प्रोटोकॉल आवश्यकता कार्यान्वयन को स्वचालित रूप से विरासत में नहीं लेते हैं। उस प्रश्न का उत्तर @objc
इसके चारों ओर प्राप्त करने के लिए एक विशेष अनुकूलन का उपयोग करता है।
समस्या की रिपोर्ट करना
मुझे लगता है कि स्विफ्ट के ओपन सोर्स प्रोजेक्ट्स पर काम करने वालों के बीच इस पर पहले से ही चर्चा हो रही है, लेकिन आप यह सुनिश्चित कर सकते हैं कि वे ऐप्पल के बग रिपोर्टर द्वारा या तो जानते हैं , जो संभवत: स्विफ्ट कोर टीम, या स्विफ्ट के बग रिपोर्टर के लिए अपना रास्ता बनाएंगे । हालाँकि, इनमें से कोई भी आपके बग को बहुत व्यापक या पहले से ज्ञात हो सकता है। स्विफ्ट टीम इस बात पर भी विचार कर सकती है कि आप एक नई भाषा सुविधा के लिए क्या देख रहे हैं, इस मामले में आपको पहले मेलिंग सूचियों की जांच करनी चाहिए ।
अपडेट करें
दिसंबर 2016 में, यह मुद्दा स्विफ्ट समुदाय को बताया गया था । इस मुद्दे को अभी भी एक मध्यम प्राथमिकता के साथ खुला के रूप में चिह्नित किया गया है, लेकिन निम्नलिखित टिप्पणी को जोड़ा गया था:
यह इरादा है। प्रत्येक एडॉप्टर में विधि के कार्यान्वयन को जोड़ने का कोई तरीका नहीं है, क्योंकि प्रोटोकॉल के अनुरूप होने के बाद एक्सटेंशन को जोड़ा जा सकता है। मुझे लगता है कि हम इसे अनुमति दे सकते हैं यदि विस्तार प्रोटोकॉल के समान मॉड्यूल में है, हालांकि।
चूंकि आपका प्रोटोकॉल आपके विस्तार के समान मॉड्यूल में है, हालांकि, आप स्विफ्ट के भविष्य के संस्करण में ऐसा करने में सक्षम हो सकते हैं।
अपडेट २
फरवरी 2017 में, इस मुद्दे को स्विफ्ट कोर टीम के सदस्यों में से एक ने निम्नलिखित संदेश के साथ आधिकारिक तौर पर "डॉन्ट डू" के रूप में बंद कर दिया था :
यह जानबूझकर है: उद्देश्य-सी क्रम की सीमाओं के कारण प्रोटोकॉल एक्सटेंशन @objc प्रविष्टि बिंदुओं को प्रस्तुत नहीं कर सकते हैं। यदि आप NSObject में @objc प्रविष्टि बिंदु जोड़ना चाहते हैं, तो NSObject का विस्तार करें।
विस्तार NSObject
या यहां तक कि UIViewController
वास्तव में आप क्या चाहते हैं पूरा नहीं होगा, लेकिन यह दुर्भाग्य से ऐसा नहीं लगता है कि यह संभव हो जाएगा।
बहुत (बहुत लंबे समय तक) भविष्य में, हम @objc
पूरी तरह से तरीकों पर निर्भरता को समाप्त करने में सक्षम हो सकते हैं , लेकिन वह समय जल्द ही कभी भी नहीं आएगा क्योंकि कोको फ्रेमवर्क वर्तमान में स्विफ्ट में नहीं लिखे गए हैं (और जब तक यह एक स्थिर एबीआई नहीं हो सकता है) ।
अपडेट ३
2019 के पतन के रूप में, यह एक समस्या से कम हो रहा है क्योंकि स्विफ्ट में अधिक से अधिक Apple रूपरेखाएं लिखी जा रही हैं। उदाहरण के लिए, यदि आप SwiftUI
इसके बजाय का उपयोग करते हैं UIKit
, तो आप समस्या को पूरी तरह से रोक देते हैं क्योंकि @objc
किसी SwiftUI
विधि का संदर्भ देते समय यह आवश्यक नहीं होगा ।
स्विफ्ट में लिखे गए Apple फ्रेमवर्क में शामिल हैं:
- SwiftUI
- RealityKit
- जोड़ना
- CryptoKit
एक को उम्मीद है कि इस पैटर्न को अब समय के साथ जारी रखा जाएगा कि स्विफ्ट आधिकारिक तौर पर एबीआई और मॉड्यूल क्रमशः स्विफ्ट 5.0 और 5.1 के रूप में स्थिर है।
@objc