I'm having a similar but slightly different problem described in: Swift protocol extension method dispatch with superclass and subclass.
The problem is related to static methods on protocols.
I have the following code:
protocol Protocol: class {
static var reuseID: String { get }
}
extension Protocol {
static var reuseID: String { return String(Self) }
}
class MyClass {
func registerClass<T where T: Protocol>(cell: T.Type) {
print(cell) // <-- Prints "SubClass"
print(cell.self) // <-- Prints "SubClass"
print(cell.reuseID) // <-- Prints "SuperClass", expected "SubClass"
}
}
class SuperClass: Protocol {}
class SubClass: SuperClass {}
print(SubClass.self) // <-- Prints "SubClass"
print(SubClass.reuseID) // <-- Prints "SubClass"
MyClass().registerClass(SubClass.self)
The behaviour is "fixed" if I remove the reuseID declaration from the protocol Protocol. Isn't this backward? According to https://nomothetis.svbtle.com/the-ghost-of-swift-bugs-future the rules for dispatch for protocol extensions are as follows:
- IF the inferred type of a variable is the protocol:
- AND the method is defined in the original protocol THEN the runtime type’s implementation is called, irrespective of whether there is a default implementation in the extension.
- AND the method is not defined in the original protocol, THEN the default implementation is called.
- ELSE IF the inferred type of the variable is the type THEN the type’s implementation is called.
The behaviour I'm observing is exactly the opposite. Any idea what I am doing wrong?