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




swift swift-protocols (10)

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

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"

स्विफ्ट में यह संभव है? यदि नहीं तो क्या ऐसा करने के लिए कोई कामकाज है?


केवल स्विफ्ट क्लासेस के लिए एक बहुत ही सरल उदाहरण है, न कि संरचनाओं या गणनाओं के लिए। ध्यान दें कि प्रोटोकॉल विधि वैकल्पिक होने पर, खेलने पर वैकल्पिक चेनिंग के दो स्तर होते हैं। इसके अलावा प्रोटोकॉल को अपनाने वाली कक्षा को इसकी घोषणा में @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!)
    }

 }

प्रोटोकॉल को "@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"

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

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

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

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

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

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

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

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

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

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

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

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

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

struct ConformsWithoutOptional {
    let required: String
}

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

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


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

उदाहरण :

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()
    }
}

तो आप प्रत्येक func को परिभाषित किए बिना प्रोटोकॉल को कार्यान्वित कर सकते हैं


समारोह घोषित करते समय बस दो शब्द डालें

@objc optional

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

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

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

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

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


स्विफ्ट 3.0 में

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

यह आपका समय बचाएगा।


यदि आप वैकल्पिक तरीकों का उपयोग करना चाहते हैं, तो आपको अपने प्रोटोकॉल को @objc विशेषता के साथ चिह्नित करना होगा :

@objc protocol MyProtocol {

    @objc optional func doSomething()

}

class MyClass : MyProtocol {

    // no error

}

अन्यथा, स्विफ्ट प्रोटोकॉल अन्य ओओ भाषाओं पर इंटरफेस की तरह व्यवहार करते हैं, जहां इंटरफेस में परिभाषित सभी विधियों को लागू किया जाना चाहिए।





swift-extensions