我发现了一个有趣的行为,似乎是一个错误…
基于行为描述了以下文章:
https://medium.com/ios-os-x-development/swift-protocol-extension-method- dispatch-6a6bf270ba94
http://nomothetis.svbtle.com/the-ghost-of-swift-bugs- future
当添加时SomeSuperclass,输出不是我期望的,而不是直接采用协议。
SomeSuperclass
protocol TheProtocol { func method1() } extension TheProtocol { func method1() { print("Called method1 from protocol extension") } func method2NotInProtocol() { print("Called method2NotInProtocol from protocol extension") } } // This is the difference - adding a superclass class SomeSuperclass: TheProtocol { } // It works as expected when it simply adopts TheProtocol, but not when it inherits from a class that adopts the protocol class MyClass: SomeSuperclass { func method1() { print("Called method1 from MyClass implementation") } func method2NotInProtocol() { print("Called method2NotInProtocol from MyClass implementation") } } let foo: TheProtocol = MyClass() foo.method1() // expect "Called method1 from MyClass implementation", got "Called method1 from protocol extension" foo.method2NotInProtocol() // Called method2NotInProtocol from protocol extension
您知道这是错误还是设计使然?一位同事建议混合继承和协议扩展可能无法按预期工作。我打算使用协议扩展来提供默认的实现…如果我做不到,那么我将不得不标记它@objc并返回到可选协议。
@objc
摘自The Swift Bugs Future的Ghost帖子,这是帖子末尾提到的协议扩展的分发规则。
因此,根据您的情况,您是说method1()在协议中定义,并且已在子类中实现。但是您的超类正在采用协议,但未实现method1(),子类只是从超类继承而未直接采用协议。这就是为什么我认为这就是为什么当您调用foo.method1()时,它没有调用第1点和第2点所述的子类实现的原因。
但是当你这样做时
class SomeSuperclass: TheProtocol { func method1(){ print("super class implementation of method1()")} } class MyClass : SomeSuperclass { override func method1() { print("Called method1 from MyClass implementation") } override func method2NotInProtocol() { print("Called method2NotInProtocol from MyClass implementation") } }
然后当你打电话时,
let foo: TheProtocol = MyClass() foo.method1() // Called method1 from MyClass implementation foo.method2NotInProtocol()
因此,此bug(似乎是bug)的解决方法是,您需要在超类中实现protocol方法,然后需要在子类中覆盖protocol方法。高温超导