यह कैसे आवश्यक है कि एक प्रोटोकॉल केवल एक विशिष्ट वर्ग द्वारा अपनाया जा सकता है


91

मुझे यह प्रोटोकॉल चाहिए:

protocol AddsMoreCommands {
     /* ... */
}

केवल उन वर्गों द्वारा अपनाई जानी चाहिए जो वर्ग से विरासत में आते हैं UIViewControllerयह पृष्ठ बताता है कि मैं यह निर्दिष्ट कर सकता हूं कि यह केवल एक वर्ग द्वारा (एक संरचना के विपरीत) लेखन द्वारा अपनाया गया है

protocol AddsMoreCommands: class {
}

लेकिन मैं यह नहीं देख सकता कि कैसे आवश्यकता है कि यह केवल किसी विशेष वर्ग द्वारा अपनाया जाए। वह पृष्ठ बाद में whereअनुरूपता की जांच करने के लिए प्रोटोकॉल एक्सटेंशन में क्लॉस जोड़ने के बारे में बात करता है लेकिन मैं यह नहीं देख सकता कि इसे कैसे अनुकूलित किया जाए।

extension AddsMoreCommands where /* what */ {
}

क्या इसे करने का कोई तरीका है? धन्यवाद!

जवाबों:


115
protocol AddsMoreCommands: class {
    // Code
}

extension AddsMoreCommands where Self: UIViewController {
    // Code
}

4
मैं तो लगभग यह ... मैंने लिखा था selfकी बजाय Self:-( आपको बहुत बहुत धन्यवाद कि ठीक काम करता है,!
emrys57

मेरे लिए, यह कुछ वाक्यात्मक विचित्रता का कारण बनता है जब मैं इसे कास्टिंग के साथ संयोजन में उपयोग करता हूं।
क्रिस प्रिंस

3
यह काम नहीं करेगा यदि आपको प्रोटोकॉल में एक संपत्ति शामिल करने की आवश्यकता है, क्योंकि एक्सटेंशन में संग्रहीत गुण नहीं हो सकते।
शिम

1
यह उचित संग्रहित कर सकता है जिसे आपको केवल इसका उपयोग करने की आवश्यकता है: objc_getAssociatedObject (स्वयं, और KeyName) के रूप में? PropertyType
मीकल Ziobro

यह भी आवश्यक है कि जब कोई लेट / AddsMoreCommandsUIViewController
वेरिएंट

80

इसे बिना एक्सटेंशन के भी प्राप्त किया जा सकता है:

protocol AddsMoreCommands: class where Self: UIViewController {
   // code
}

EDITED 2017/11/04 : जैसा कि ज़िग ने बताया, यह Xcode 9.1 पर एक चेतावनी उत्पन्न करता है। वर्तमान में चेतावनी को हटाने के लिए स्विफ्ट प्रोजेक्ट (SR-6265) पर एक समस्या है , मैं इस पर नज़र रखूंगा और तदनुसार उत्तर को अपडेट करूंगा।

EDITED 2018/09/29 : classजरूरत है अगर वैरिएबल जो इंस्टेंस को संचित करेगा उसे कमजोर होना चाहिए (जैसे कि एक प्रतिनिधि)। यदि आपको एक कमजोर चर की आवश्यकता नहीं है, तो आप इसे छोड़ सकते हैं classऔर बस निम्नलिखित लिख सकते हैं और कोई चेतावनी नहीं होगी:

protocol AddsMoreCommands where Self: UIViewController {
   // code
}

5
यह कितना संयोग की बात है कि मैंने दो साल पुराने सवाल पर क्लिक किया और एक घंटे पहले पोस्ट किया एक सही समाधान
खोजा

Xcode 9.1 अब मुझे इस कहावत के बारे में एक चेतावनी दे रहा है: निरर्थक लेआउट बाधा 'स्व': 'AnyObject'। लेआउट बाधा बाधा 'स्व': 'AnyObject' यहाँ निहित है। मेरे कोड को स्वीकृत उत्तर के प्रारूप में बदलना अधिक अच्छा लगता है।
जिग

2
Xcode के रूप में 9.1 वर्ग केवल प्रोटोकॉल अब के AnyObjectबजाय का उपयोग करें classprotocol AddsMoreCommands: AnyObject where Self: UIViewController { // code }
डोडर्जियो

@ डोडिएगो अभी भी एक ही चेतावनी का उपयोग कर रहा हैAnyObject
rgkobashi

1
@ DávidPásztor आप सही हैं, हालाँकि यदि आप इसे एक संरचनात्मक पैटर्न पर उपयोग करना चाहते हैं जैसे कि प्रतिनिधिमंडल, संपत्ति को कमजोर बनाने में सक्षम होने के लिए ´class´ को स्पष्ट रूप से जोड़ना आवश्यक है :)
rgkobashi 31/18

48

पिछले उत्तर में एक समस्या के कारण मैं इस घोषणा के साथ समाप्त हुआ:

protocol AddsMoreCommands where Self : UIViewController { 
    // protocol stuff here  
}

Xcode 9.1 में कोई चेतावनी नहीं


5
अगर मैं गलत हूं तो मुझे सुधारें, लेकिन ऊपर दिए गए समाधान (जो Xcode 9.1 और ऊपर की तरफ एक चेतावनी उत्पन्न कर रहा है) पर इस के साथ समस्या यह है कि आप प्रतिनिधि को कमजोर घोषित नहीं कर सकते?
काइल गोसलान

इसके अलावा, जब मैं स्विफ्ट 4.1 के साथ इस समाधान का उपयोग करता हूं, तो मुझे उन संपत्तियों को डालना होगा AddsMoreCommands, UIViewControllerजिनसे मैं बचना चाहता था ...
fl034

9
टाइप कास्ट से बचने के लिए, आप ऐसा कर सकते हैं:typealias AddsMoreCommandsViewController = UIViewController & AddsMoreCommands
pl

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