ios - swift可选协议 - 如何在Swift协议中定义可选方法?




swift协议扩展 (10)

以下是委托模式的具体示例。

设置您的协议:

@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?()

在Swift中可能吗? 如果没有,那么是否有解决方法来做到这一点?


为了说明安托万的答案的机制:

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"

Swift 3.0中

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

它会节省你的时间。


在Swift 2.0中,可以添加协议的默认实现。 这为协议中的可选方法创建了一种新方法。

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

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

创建可选的协议方法并不是一个非常好的方法,但是可以在协议回调中使用结构。

我在这里写了一个小小的摘要: http://www.avanderlee.com/swift-2-0/optional-protocol-methods/ : http://www.avanderlee.com/swift-2-0/optional-protocol-methods/


如果你想在纯粹的swift中完成,最好的方法是提供一个默认的实现细节,如果你返回一个Swift类型,比如像Swift类型的结构

例如:

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的情况下实现协议


@optional放在方法或属性前面。


我认为在问你如何实现一个可选的协议方法之前,你应该问为什么你应该实现一个。

如果我们将Swift协议看作传统面向对象编程中的接口 ,可选方法没有多大意义,并且可能更好的解决方案是创建默认实现,或将协议分成一组协议(可能带有一些继承关系以表示方案中可能的方法组合。

有关进一步阅读,请参阅https://useyourloaf.com/blog/swift-optional-protocol-methods/ ,该文章对此进行了很好的概述。


由于有关如何使用可选修饰符@objc属性来定义可选需求协议的一些答案,我将举例说明如何使用协议扩展定义可选协议。

下面的代码是Swift 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*

请注意协议扩展方法不能被Objective-C代码调用,更糟糕的是Swift团队无法修复它。 https://bugs.swift.org/browse/SR-492


这里是一个非常简单的示例,仅适用于swift类,而不适用于结构或枚举。 请注意,协议方法是可选的,有两个级别的可选链接。 此外,采用该协议的类在其声明中需要@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属性标记你的协议:

@objc protocol MyProtocol {

    @objc optional func doSomething()

}

class MyClass : MyProtocol {

    // no error

}

否则,Swift协议的行为就像其他OO语言的接口一样,必须实现接口中定义的所有方法。





swift-extensions