让我们假设我在Swift中有一个带有默认实现的方法的协议FooProtocol:
protocol FooProtocol {
func foo()
}
extension FooProtocol {
func foo() {
print("protocol")
}
}和带有强制转换实例的类FooClass:
class FooClass : FooProtocol {
func foo() {
print("class")
}
}
let A = FooClass() as FooProtocol
A.foo()不出所料,"class“将在控制台中打印出来。然而,如果我将我协议的foo()方法设为可选-- " protocol“将被打印出来。
@objc protocol FooProtocol {
@objc optional func foo()
}但是如果我调用A.foo?()而不是A.foo() - "class“将被再次打印。
我想知道,只是出于理论目的,这里到底发生了什么?任何解释都是值得感谢的。
发布于 2020-03-11 01:36:26
不能在没有可选链接的情况下调用optional协议方法。例如,如果您注释掉
extension FooProtocol {
func foo() {
...当你尝试调用A.foo()时,你会得到一个编译错误:
可选类型的
值'(() -> ())?‘必须取消包装为'() -> ()‘类型的值
如您所见,optional的签名甚至不同于non-optional。因此,通过调用A.foo(),您不是在调用您实现的方法,而是在直接调用默认协议实现。
这也是有意义的,因为@objc optional的主要reason是使用Objective C的插值,其中默认协议实现将不可见。因此,依赖于协议函数来实现objc函数会在swift和objective c上产生不同的结果,这是不希望的。
我不能说在同一函数上同时使用optional和默认协议实现是否有任何漏洞。但问题是:你真的需要它吗?
如果你关心插值,你需要Swift和Objective c的相等解决方案,这意味着你更需要基本的协议实现,Swift和objc都可以继承
如果您不需要插值,那么您实际上不需要可选的,并且可以仅依赖于缺省协议实现。
https://stackoverflow.com/questions/60618440
复制相似问题