在Swift中可以吗?如果不是,那么是否有解决方法?


当前回答

在协议中定义函数并为该协议创建扩展,然后为您想要作为可选使用的函数创建空实现。

其他回答

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

如果我们将swift协议视为经典的面向对象编程中的接口,那么可选方法就没有多大意义,也许更好的解决方案是创建默认实现,或将协议分离为一组协议(可能在它们之间具有一些继承关系),以表示协议中方法的可能组合。

欲进一步阅读,请参阅https://useyourloaf.com/blog/swift-optional-protocol-methods/,该网站对此问题有很好的概述。

如果你想在纯swift中做到这一点,最好的方法是提供一个默认实现,特别是如果你返回一个swift类型,例如struct与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

要在swift中定义可选协议,你应该在协议声明和协议中的属性/方法声明之前使用@objc关键字。 下面是协议的可选属性示例。

@objc protocol Protocol {

  @objc optional var name:String?

}

//现在,如果尝试在代码中实现该协议,将不会强制在类中包含该函数。

class MyClass: Protocol {

   // No error

}

另一种方法是使用协议扩展,我们也可以给出该协议的默认实现。所以协议的功能是可选的。

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

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 2及以后的版本中,可以添加协议的默认实现。这为协议中的可选方法提供了一种新的方式。

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

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

这不是一个创建可选协议方法的好方法,但是给了你在协议回调中使用struct的可能性。

我在这里写了一个小总结: https://www.avanderlee.com/swift-2-0/optional-protocol-methods/