स्विफ्ट प्रोटोकॉल में वैकल्पिक तरीकों को कैसे परिभाषित करें?


359

क्या स्विफ्ट में यह संभव है? यदि नहीं, तो क्या इसे करने के लिए वर्कअराउंड है?


1
मैंने अपने जवाब को अपडेट करने के लिए अंत में खुद को प्रेरित किया, आप इसे स्वीकार करने पर पुनर्विचार कर सकते हैं।
आकाशवाणी '

@akashivskyy मैं आपके उत्तर को स्वीकार करता हूं क्योंकि यह सभी उपलब्ध विकल्पों और उनके पेशेवरों और विपक्षों को बेहतर दिखाता है।
सेल्विन

जवाबों:


503

1. डिफ़ॉल्ट कार्यान्वयन (पसंदीदा) का उपयोग करना।

protocol MyProtocol {
    func doSomething()
}

extension MyProtocol {
    func doSomething() {
        /* return a default value or just leave empty */
    }
}

struct MyStruct: MyProtocol {
    /* no compile error */
}

लाभ

  • कोई उद्देश्य-सी रनटाइम शामिल नहीं है (ठीक है, कम से कम स्पष्ट रूप से नहीं)। इसका मतलब है कि आप इसके लिए स्ट्रक्चर, एनम और नॉन- NSObjectक्लास कंफर्म कर सकते हैं । इसके अलावा, इसका मतलब है कि आप शक्तिशाली जेनरिक प्रणाली का लाभ उठा सकते हैं।

  • आप हमेशा सुनिश्चित कर सकते हैं कि ऐसे प्रोटोकॉल के अनुरूप प्रकारों का सामना करते समय सभी आवश्यकताओं को पूरा किया जाए। यह हमेशा या तो ठोस कार्यान्वयन है या डिफ़ॉल्ट रूप से। इस तरह से "इंटरफेस" या "अनुबंध" अन्य भाषाओं में व्यवहार करते हैं।

नुकसान

  • गैर- Voidआवश्यकताओं के लिए, आपको एक उचित डिफ़ॉल्ट मान होना चाहिए , जो हमेशा संभव नहीं होता है। हालाँकि, जब आप इस समस्या का सामना करते हैं, तो इसका मतलब है कि या तो इस तरह की आवश्यकता का वास्तव में कोई डिफ़ॉल्ट कार्यान्वयन नहीं होना चाहिए, या कि आपके द्वारा एपीआई डिजाइन के दौरान गलती की गई है।

  • आप एक डिफ़ॉल्ट कार्यान्वयन और किसी भी कार्यान्वयन के बीच अंतर नहीं कर सकते , कम से कम विशेष रिटर्न मानों के साथ उस समस्या को संबोधित किए बिना। निम्नलिखित उदाहरण पर विचार करें:

    protocol SomeParserDelegate {
        func validate(value: Any) -> Bool
    }

    यदि आप एक डिफ़ॉल्ट कार्यान्वयन प्रदान करते हैं जो अभी वापस आता है true- यह पहली नज़र में ठीक है। अब, निम्नलिखित छद्म कोड पर विचार करें:

    final class SomeParser {
        func parse(data: Data) -> [Any] {
            if /* delegate.validate(value:) is not implemented */ {
                /* parse very fast without validating */
            } else {
                /* parse and validate every value */
            }
        }
    }

    इस तरह के अनुकूलन को लागू करने का कोई तरीका नहीं है - आप यह नहीं जान सकते कि आपका प्रतिनिधि एक विधि लागू करता है या नहीं।

    यद्यपि इस समस्या को दूर करने के लिए कई अलग-अलग तरीके हैं (वैकल्पिक बंद का उपयोग करके, कुछ नाम के लिए अलग-अलग संचालन के लिए अलग-अलग प्रतिनिधि ऑब्जेक्ट), यह उदाहरण समस्या को स्पष्ट रूप से प्रस्तुत करता है।


2. उपयोग करना @objc optional

@objc protocol MyProtocol {
    @objc optional func doSomething()
}

class MyClass: NSObject, MyProtocol {
    /* no compile error */
}

लाभ

  • किसी डिफ़ॉल्ट कार्यान्वयन की आवश्यकता नहीं है। आप बस एक वैकल्पिक विधि या एक चर घोषित करते हैं और आप जाने के लिए तैयार हैं।

नुकसान

  • यह ऑब्जेक्टिव-सी संगत होने के लिए सभी अनुरूप प्रकारों की आवश्यकता के द्वारा आपके प्रोटोकॉल की क्षमताओं को गंभीर रूप से सीमित करता है। इसका मतलब है, केवल कक्षाएं जो विरासत में मिली NSObjectहैं, ऐसे प्रोटोकॉल के अनुरूप हो सकती हैं। कोई संरचना, कोई एनम, कोई संबद्ध प्रकार नहीं।

  • यदि वैकल्पिक विधि इसे लागू करती है तो आपको वैकल्पिक रूप से कॉल या चेक करके वैकल्पिक पद्धति लागू करने पर हमेशा जांच करनी चाहिए । यदि आप वैकल्पिक तरीकों को अक्सर कॉल कर रहे हैं तो यह बहुत सारे बॉयलरप्लेट को पेश कर सकता है।


17
एक विस्तार (नीचे) का उपयोग करते हुए तेजी से वैकल्पिक तरीकों के बेहतर तरीके को देखें
डैनियल कानन

1
और एक उदाहरण में एक वैकल्पिक प्रोटोकॉल विधि के समर्थन के लिए एक परीक्षण कैसे होता है? respondsToSelector?
देवियो 1

3
बस यह मत करो! स्विफ्ट एक कारण के लिए प्रोटोकॉल में वैकल्पिक विधि का समर्थन नहीं करता है।
fpg1503

2
यह विधि मापदंडों में वैकल्पिक का समर्थन नहीं करती है। यानी आप ऐसा नहीं कर सकते हैंoptional func doSomething(param: Int?)
SoftDesigner

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

394

स्विफ्ट 2 और उसके बाद किसी प्रोटोकॉल के डिफ़ॉल्ट कार्यान्वयन को जोड़ना संभव है। यह प्रोटोकॉल में वैकल्पिक तरीकों का एक नया तरीका बनाता है।

protocol MyProtocol {
    func doSomethingNonOptionalMethod()
    func doSomethingOptionalMethod()
}

extension MyProtocol {
    func doSomethingOptionalMethod(){ 
        // leaving this empty 
    }
}

यह वैकल्पिक प्रोटोकॉल विधियों को बनाने में वास्तव में अच्छा तरीका नहीं है, लेकिन आपको प्रोटोकॉल कॉलबैक में संरचना का उपयोग करने की संभावना देता है।

मैंने यहाँ एक छोटा सा सारांश लिखा: https://www.avanderlee.com/swift-2-0/optional-protocol-methods/


2
शायद स्विफ्ट में ऐसा करने का यह सबसे साफ तरीका है। बहुत बुरा यह स्विफ्ट 2.0 से पहले काम नहीं करता है।
एंटाल्पी

13
@MattQuiros मुझे लग रहा है कि आप वास्तव में फ़ंक्शन को प्रोटोकॉल की परिभाषा में घोषित करने की आवश्यकता है, अन्यथा नो-ऑप एक्सटेंशन फ़ंक्शन को आपकी कक्षाओं में ओवरराइड नहीं किया जाता है जो प्रोटोकॉल के अनुरूप हैं।
इयान पीयर्स

3
@IanPearce सही है, और यह डिज़ाइन द्वारा प्रतीत होता है। WWDC में "प्रोटोकॉल ओरिएंटेड प्रोग्रामिंग" टॉक (408) में, वे मुख्य प्रोटोकॉल में विधियों के बारे में बात करते हैं जो "कस्टमाइज़िंग पॉइंट" हैं जो कि अनुरूप प्रकारों की पेशकश करते हैं। अनुकूलन का एक आवश्यक बिंदु एक विस्तार में परिभाषा प्राप्त नहीं करता है; एक वैकल्पिक बिंदु करता है। आम तौर पर अनुकूलित नहीं किया जाना चाहिए कि प्रोटोकॉल पर तरीके पूरी तरह से अनुकूलित करने के लिए अस्वीकार करने के लिए विस्तार में परिभाषित / परिभाषित किया गया है जब तक कि आप विशेष रूप से अपने डायनामिक टाइप करने के लिए नीचे नहीं डालते हैं, ताकि आपको पता चल सके कि आप कस्टमर का कस्टम कार्यान्वयन चाहते हैं।
मथियास

4
@FranklinYu आप ऐसा कर सकते हैं, लेकिन तब आप अपने एपीआई डिज़ाइन को 'थ्रो' के साथ जोड़ रहे हैं, जहाँ इसकी आवश्यकता नहीं है। मुझे "माइक्रो प्रोटोकॉल" का विचार अधिक पसंद है। उदाहरण के लिए प्रत्येक विधि एक प्रोटोकॉल की पुष्टि करती है और फिर आप इसके लिए जांच कर सकते हैं: यदि ऑब्जेक्ट प्रोटोकॉल है
Darko

3
@Antoine मुझे लगता है कि आपको फ़ंक्शन को सार्वजनिक रूप से करना चाहिए, क्योंकि प्रोटोकॉल में फ़ंक्शन परिभाषा द्वारा सार्वजनिक हैं। जब आपके मॉड्यूल के बाहर प्रोटोकॉल का उपयोग किया जाएगा तो आपका समाधान काम नहीं करेगा।
वादिम ईसेनबर्ग

39

चूंकि वैकल्पिक संशोधक और @objc विशेषता का उपयोग करने के बारे में कुछ उत्तर हैं वैकल्पिक आवश्यकता प्रोटोकॉल को परिभाषित , इसलिए मैं एक नमूना दूंगा कि कैसे प्रोटोकॉल एक्सटेंशन का उपयोग वैकल्पिक प्रोटोकॉल को परिभाषित किया जाए।

नीचे कोड स्विफ्ट 3. * है।

/// Protocol has empty default implementation of the following methods making them optional to implement:
/// `cancel()`
protocol Cancelable {

    /// default implementation is empty.
    func cancel()
}

extension Cancelable {

    func cancel() {}
}

class Plane: Cancelable {
  //Since cancel() have default implementation, that is optional to class Plane
}

let plane = Plane()
plane.cancel()
// Print out *United Airlines can't cancelable*

कृपया ध्यान दें कि प्रोटोकॉल एक्सटेंशन के तरीके ऑब्जेक्टिव-सी कोड द्वारा लागू नहीं किए जा सकते हैं, और इससे भी बदतर स्विफ्ट टीम इसे ठीक नहीं करेगी। https://bugs.swift.org/browse/SR-492


1
बहुत बढ़िया! यह सही उत्तर होना चाहिए क्योंकि यह ऑब्जेक्ट-सी रनटाइम को शामिल किए बिना समस्या को हल करता है।
लुकास

वास्तव में एक अच्छा!
tania_S

तेजी से प्रलेखन से - "एक्सटेंशन द्वारा प्रदान की गई डिफ़ॉल्ट कार्यान्वयन के साथ प्रोटोकॉल की आवश्यकताएं वैकल्पिक प्रोटोकॉल आवश्यकताओं से अलग हैं। हालांकि अनुरूप प्रकारों को या तो अपने स्वयं के कार्यान्वयन को प्रदान करने की आवश्यकता नहीं है, डिफ़ॉल्ट कार्यान्वयन के साथ आवश्यकताओं को वैकल्पिक चेनिंग के बिना कहा जा सकता है।"
मेस ओस

34

यहां अन्य उत्तरों में प्रोटोकॉल को "@objc" के रूप में चिह्नित किया गया है जो स्विफ्ट-विशिष्ट प्रकारों का उपयोग करते समय काम नहीं करता है।

struct Info {
    var height: Int
    var weight: Int
} 

@objc protocol Health {
    func isInfoHealthy(info: Info) -> Bool
} 
//Error "Method cannot be marked @objc because the type of the parameter cannot be represented in Objective-C"

वैकल्पिक प्रोटोकॉल की घोषणा करने के लिए जो तेजी से काम करते हैं, फ़ंक्शंस के बजाय फ़ंक्शंस को चर के रूप में घोषित करते हैं।

protocol Health {
    var isInfoHealthy: (Info) -> (Bool)? { get set }
}

और फिर प्रोटोकॉल को निम्नानुसार लागू करें

class Human: Health {
    var isInfoHealthy: (Info) -> (Bool)? = { info in
        if info.weight < 200 && info.height > 72 {
            return true
        }
        return false
    }
    //Or leave out the implementation and declare it as:  
    //var isInfoHealthy: (Info) -> (Bool)?
}

फिर आप "" का उपयोग कर सकते हैं? यह जाँचने के लिए कि फ़ंक्शन लागू किया गया है या नहीं

func returnEntity() -> Health {
    return Human()
}

var anEntity: Health = returnEntity()

var isHealthy = anEntity.isInfoHealthy(Info(height: 75, weight: 150))? 
//"isHealthy" is true

3
इस समाधान के साथ आप किसी भी प्रोटोकॉल फ़ंक्शन के भीतर से स्वयं तक नहीं पहुंच सकते। यह कुछ मामलों में समस्याएँ पैदा कर सकता है!
जॉर्ज ग्रीन

1
@GeorgeGreen आप स्वयं पहुँच सकते हैं। फ़ंक्शन चर को आलसी के रूप में चिह्नित करें और क्लोजर के अंदर कैप्चर सूची का उपयोग करें ।
ज़ग

केवल वर्ग, प्रोटोकॉल, विधियाँ और गुण @objc का उपयोग कर सकते हैं। यदि आप @ objc प्रोटोकॉल विधि डिफिनेशन में Enum पैरामीटर का उपयोग कर रहे हैं, तो आप बर्बाद हैं।
खुनशान

1
@ सुखन, इस विधि के लिए कुछ भी @ objc अंकित नहीं होना चाहिए, आप किस विषय का उल्लेख कर रहे हैं?
ज़ग

इस विषय पर एक जानकारी जो कि एनम का उपयोग तेज और objc के बीच नहीं किया जा सकता है, जो अन्य कथनों के लिए @objc कीवर्ड के साथ ब्रिज की जा सकती है।
खुनशान

34

यहां प्रतिनिधिमंडल पैटर्न के साथ एक ठोस उदाहरण है।

अपना प्रोटोकॉल सेट करें:

@objc protocol MyProtocol:class
{
    func requiredMethod()
    optional func optionalMethod()
}

class MyClass: NSObject
{
    weak var delegate:MyProtocol?

    func callDelegate()
    {
        delegate?.requiredMethod()
        delegate?.optionalMethod?()
    }
}

एक वर्ग के लिए प्रतिनिधि सेट करें और प्रोटोकॉल को लागू करें। देखें कि वैकल्पिक विधि को लागू करने की आवश्यकता नहीं है।

class AnotherClass: NSObject, MyProtocol
{
    init()
    {
        super.init()

        let myInstance = MyClass()
        myInstance.delegate = self
    }

    func requiredMethod()
    {
    }
}

एक महत्वपूर्ण बात यह है कि वैकल्पिक विधि वैकल्पिक है और एक "की आवश्यकता है?" जब बुला रहा है। दूसरे प्रश्न चिह्न का उल्लेख करें।

delegate?.optionalMethod?()

2
यह सही उत्तर होना चाहिए। सरल, स्वच्छ और व्याख्यात्मक।
इकलौती

मैं मानता हूं, यह उत्तर छोटा, मीठा और सीधे बिंदु पर है। धन्यवाद!
लुआंड्रे

31

में स्विफ्ट 3.0

@objc protocol CounterDataSource {
    @objc optional func increment(forCount count: Int) -> Int
    @objc optional var fixedIncrement: Int { get }
}

इससे आपका समय बचेगा।


6
@objcसभी सदस्यों पर अब किसी भी स्रोत की आवश्यकता क्यों है?
DevAndArtist

@ गौतम सरेरिया: आपको क्या लगता है कि यह सबसे अच्छा तरीका है या खाली एक्सटेंशन के तरीके बनाना?
eonist

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

27
  • आपको optionalप्रत्येक विधि से पहले कीवर्ड जोड़ना होगा ।
  • हालाँकि, कृपया ध्यान दें कि इस कार्य के लिए, आपके प्रोटोकॉल को @objc विशेषता के साथ चिह्नित किया जाना चाहिए।
  • इसका अर्थ है कि यह प्रोटोकॉल कक्षाओं पर लागू होगा, लेकिन संरचनाओं पर नहीं।

मामूली सुधार (संपादित करने के लिए बहुत छोटा!), लेकिन यह 'वैकल्पिक' नहीं '@ दत्तक' होना चाहिए
अली

5
इसके लिए आपको प्रोटोकॉल को लागू करने वाले वर्ग को चिह्नित करना होगा @objc, न कि केवल प्रोटोकॉल को।
जॉनथॉन सुलिंगर

13

प्रोटोकॉल विरासत के साथ एक शुद्ध स्विफ्ट दृष्टिकोण:

//Required methods
protocol MyProtocol {
    func foo()
}

//Optional methods
protocol MyExtendedProtocol: MyProtocol {
    func bar()
}

class MyClass {
    var delegate: MyProtocol
    func myMethod() {
        (delegate as? MyExtendedProtocol).bar()
    }
}

11

एंटोनी के उत्तर के यांत्रिकी को स्पष्ट करने के लिए:

protocol SomeProtocol {
    func aMethod()
}

extension SomeProtocol {
    func aMethod() {
        print("extensionImplementation")
    }
}

class protocolImplementingObject: SomeProtocol {

}

class protocolImplementingMethodOverridingObject: SomeProtocol {
    func aMethod() {
        print("classImplementation")
    }
}

let noOverride = protocolImplementingObject()
let override = protocolImplementingMethodOverridingObject()

noOverride.aMethod() //prints "extensionImplementation"
override.aMethod() //prints "classImplementation"

8

मुझे लगता है कि यह पूछने से पहले कि आप एक वैकल्पिक प्रोटोकॉल विधि कैसे लागू कर सकते हैं, आपको यह पूछना चाहिए कि आपको एक को क्यों लागू करना चाहिए।

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

आगे पढ़ने के लिए, https://useyourloaf.com/blog/swift-optional-protocol-methods/ देखें , जो इस मामले पर एक उत्कृष्ट अवलोकन देता है।


इस। यह SOLID सॉफ्टवेयर विकास सिद्धांतों में "I" सिद्धांत का पालन है ।
एरिक

7

मूल प्रश्न से थोड़ा हटकर विषय, लेकिन यह एंटोनी के विचार का निर्माण करता है और मुझे लगा कि यह किसी की मदद कर सकता है।

आप प्रोटोकॉल एक्सटेंशन के साथ संरचना के लिए गणना किए गए गुणों को वैकल्पिक भी बना सकते हैं।

आप प्रोटोकॉल पर एक संपत्ति वैकल्पिक कर सकते हैं

protocol SomeProtocol {
    var required: String { get }
    var optional: String? { get }
}

प्रोटोकॉल एक्सटेंशन में डमी गणना की गई संपत्ति को लागू करें

extension SomeProtocol {
    var optional: String? { return nil }
}

और अब आप उन स्ट्रक्चर्स का उपयोग कर सकते हैं जो वैकल्पिक संपत्ति को लागू करते हैं या नहीं करते हैं

struct ConformsWithoutOptional {
    let required: String
}

struct ConformsWithOptional {
    let required: String
    let optional: String?
}

मैंने यह भी लिखा है कि अपने ब्लॉग पर स्विफ्ट प्रोटोकॉल में वैकल्पिक गुण कैसे करें , जो मैं स्विफ्ट 2 रिलीज के माध्यम से मामले में बदलाव के लिए अद्यतन रखूंगा


5

वैकल्पिक और आवश्यक प्रतिनिधि तरीके कैसे बनाएं।

@objc protocol InterViewDelegate:class {

    @objc optional func optfunc()  //    This is optional
    func requiredfunc()//     This is required 

}

3

यहां केवल स्विफ्ट क्लासेस के लिए एक बहुत ही सरल उदाहरण है, और संरचनाओं या गणना के लिए नहीं। ध्यान दें कि प्रोटोकॉल विधि वैकल्पिक है, प्ले में वैकल्पिक स्तर के दो स्तर हैं। इसके अलावा प्रोटोकॉल अपनाने वाले वर्ग को अपनी घोषणा में @objc विशेषता की आवश्यकता होती है।

@objc protocol CollectionOfDataDelegate{
   optional func indexDidChange(index: Int)
}


@objc class RootView: CollectionOfDataDelegate{

    var data = CollectionOfData()

   init(){
      data.delegate = self
      data.indexIsNow()
   }

  func indexDidChange(index: Int) {
      println("The index is currently: \(index)")
  }

}

class CollectionOfData{
    var index : Int?
    weak var delegate : CollectionOfDataDelegate?

   func indexIsNow(){
      index = 23
      delegate?.indexDidChange?(index!)
    }

 }

क्या आप " प्ले में वैकल्पिक के दो स्तरों " का थोड़ा और वर्णन कर सकते हैं , जिसका नाम है delegate?.indexDidChange?(index!):?
Unheilig

2
यदि हमने प्रोटोकॉल को एक गैर वैकल्पिक विधि की तरह लिखा है: protocol CollectionOfDataDelegate{ func indexDidChange(index: Int) } तो आप इसे प्रश्नवाचक चिह्न के बिना कहेंगे: delegate?.indexDidChange(index!) जब आप किसी प्रोटोकॉल में एक विधि के लिए एक वैकल्पिक आवश्यकता निर्धारित करते हैं, तो उस प्रकार के अनुरूप जो उस पद्धति को लागू नहीं कर सकता है। , इसलिए ?इसका उपयोग कार्यान्वयन के लिए जांच करने के लिए किया जाता है और यदि कोई है तो कार्यक्रम दुर्घटनाग्रस्त नहीं होगा। @ यूनीलिग
आशीर्वाद लोप

weak var delegate : CollectionOfDataDelegate?(कमजोर संदर्भ सुनिश्चित करें?)
अल्फी हंससेन

@BlessingLopes क्या आप delegate?अपने उत्तर के उपयोग की अपनी व्याख्या जोड़ सकते हैं ? यह जानकारी वास्तव में भविष्य में दूसरों के लिए होनी चाहिए। मैं इसे उभारना चाहता हूं, लेकिन यह जानकारी वास्तव में उत्तर में होनी चाहिए।
जॉनथॉन सुलिंगर

3

यदि आप इसे शुद्ध स्विफ्ट में करना चाहते हैं तो सबसे अच्छा तरीका यह है कि यदि आप एक स्विफ्ट प्रकार प्रदान करें तो यदि आप स्विफ्ट प्रकार लौटाते हैं, जैसे स्विफ्ट प्रकारों के साथ संरचना

उदाहरण :

struct magicDatas {
    var damagePoints : Int?
    var manaPoints : Int?
}

protocol magicCastDelegate {
    func castFire() -> magicDatas
    func castIce() -> magicDatas
}

extension magicCastDelegate {
    func castFire() -> magicDatas {
        return magicDatas()
    }

    func castIce() -> magicDatas {
        return magicDatas()
    }
}

फिर आप हर फंक को परिभाषित किए बिना प्रोटोकॉल को लागू कर सकते हैं


2

दो तरीके हैं जिनसे आप स्विफ्ट प्रोटोकॉल में वैकल्पिक विधि बना सकते हैं।

1 - पहला विकल्प @objc विशेषता का उपयोग करके अपने प्रोटोकॉल को चिह्नित करना है। हालांकि इसका मतलब यह है कि इसे केवल कक्षाओं द्वारा अपनाया जा सकता है, इसका मतलब है कि आप इस तरह से वैकल्पिक होने के लिए अलग-अलग तरीकों को चिह्नित करते हैं:

@objc protocol MyProtocol {
    @objc optional func optionalMethod()
}

2 - एक तेजी से रास्ता: यह विकल्प बेहतर है। वैकल्पिक तरीकों के डिफ़ॉल्ट कार्यान्वयन को लिखें, जो इस तरह से कुछ भी नहीं करते हैं।

protocol MyProtocol {
    func optionalMethod()
    func notOptionalMethod()
}

extension MyProtocol {

    func optionalMethod() {
        //this is a empty implementation to allow this method to be optional
    }
}

स्विफ्ट में एक सुविधा है जिसे एक्सटेंशन कहा जाता है जो हमें उन तरीकों के लिए एक डिफ़ॉल्ट कार्यान्वयन प्रदान करने की अनुमति देता है जो हम वैकल्पिक होना चाहते हैं।


0

एक विकल्प उन्हें वैकल्पिक फ़ंक्शन चर के रूप में संग्रहीत करना है:

struct MyAwesomeStruct {
    var myWonderfulFunction : Optional<(Int) -> Int> = nil
}

let squareCalculator =
    MyAwesomeStruct(myWonderfulFunction: { input in return input * input })
let thisShouldBeFour = squareCalculator.myWonderfulFunction!(2)

-1

प्रोटोकॉल में फ़ंक्शन को परिभाषित करें और उस प्रोटोकॉल के लिए एक्सटेंशन बनाएं, फिर फ़ंक्शन के लिए खाली कार्यान्वयन बनाएं जिसे आप वैकल्पिक के रूप में उपयोग करना चाहते हैं।


-2

Optional Protocolस्विफ्ट में परिभाषित करने के लिए आपको उस प्रोटोकॉल के अंदर घोषणा और / घोषणा @objcसे पहले कीवर्ड का उपयोग करना चाहिए । नीचे एक प्रोटोकॉल की वैकल्पिक संपत्ति का एक नमूना है।Protocolattributemethod

@objc protocol Protocol {

  @objc optional var name:String?

}

class MyClass: Protocol {

   // No error

}

2
हालांकि यह इस सवाल का जवाब दे सकता है कि इस मुद्दे को हल करने में मदद करने के बारे में कुछ विवरण जोड़ना बेहतर होगा। कृपया पढ़ें कि मैं और अधिक जानने के लिए एक अच्छा उत्तर कैसे लिखूं
रोशन पिटिगला

-23

@optionalतरीकों या गुणों के सामने रखें ।


कंपाइलर त्रुटि: 'वैकल्पिक' विशेषता केवल @objc प्रोटोकॉल के सदस्यों पर ही लागू की जा सकती है।
सेल्विन

3
@optionalसही कीवर्ड भी नहीं है। यह है optional, और आपको वर्ग और प्रोटोकॉल को @objcविशेषता घोषित करना चाहिए ।
जॉनथॉन सुलिंगर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.