У меня похожая, но немного другая проблема, описанная в: Swift диспетчеризация метода расширения протокола с суперклассом и подклассом.
Проблема связана со статическими методами в протоколах.
У меня есть следующий код:
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)
Поведение «исправлено», если я удаляю объявление reuseID из протокола Protocol. Разве это не отсталость? Согласно https://nomothetis.svbtle.com/the-ghost-of-swift-bugs-future правила отправки расширений протокола следующие:
- ЕСЛИ предполагаемым типом переменной является протокол:
- И метод определен в исходном протоколе, ТОГДА вызывается реализация типа времени выполнения, независимо от того, есть ли в расширении реализация по умолчанию.
- И метод не определен в исходном протоколе, ТОГДА вызывается реализация по умолчанию.
- ИНАЧЕ, ЕСЛИ предполагаемый тип переменной является типом, ТО вызывается реализация типа.
Поведение, которое я наблюдаю, прямо противоположное. Любая идея, что я делаю неправильно?