Ios 协议扩展和子类

Ios 协议扩展和子类,ios,swift,protocols,Ios,Swift,Protocols,我想知道为什么下面没有打印出我认为应该打印的内容 /* Fails */ protocol TheProtocol { func update() } class A: TheProtocol { } class B : A {} extension TheProtocol { func update() { print("Called update from TheProtocol") } } extension TheProtocol wher

我想知道为什么下面没有打印出我认为应该打印的内容

/* Fails */
protocol TheProtocol {
    func update()
}

class A: TheProtocol {
}

class B : A {}

extension TheProtocol {
    func update() {
        print("Called update from TheProtocol")
    }
}

extension TheProtocol where Self: B {
    func update() {
        print("Called update from B")
    }
}

let instanceB = B()
instanceB.update()

let instanceBViaProtocol:TheProtocol = B()
instanceBViaProtocol.update()
这将打印以下内容:

Called update from B
Called update from TheProtocol // Why not: Called update from B (extension)
我特别想知道为什么

instanceBViaProtocol.update()
不在协议的扩展中执行update():

extension TheProtocol where Self: B {
    func update() {
        print("Called update from B")
    }
}
我想会的,因为B继承了A,A采用了协议,所以我认为B也会隐式采用协议。 将协议采用从A移到B会产生预期的结果

protocol TheProtocol {
    func update()
}

class A { // Remove TheProtocol
}

class B : A, TheProtocol {} // Add TheProtocol

extension TheProtocol {
    func update() {
        print("Called update from TheProtocol")
    }
}

extension TheProtocol where Self: B {
    func update() {
        print("Called update from B")
    }
}

let instanceB = B()
instanceB.update()

let instanceBViaProtocol:TheProtocol = B()
instanceBViaProtocol.update()
结果:

Called update from B
Called update from B

我看了一眼,但是我想不出来。在采用该协议的实体的子类上是否不支持扩展方法

答案是方法分派+

方法分派是编译器在调用方法时选择要执行的实现的机制。Swift采用三种方法调度。你可以读到它

分派方法由引用的类型而不是实例的类型决定。在您的案例中,引用类型是协议

let instanceBViaProtocol:TheProtocol = B()
instanceBViaProtocol.update()
您有一个协议扩展,它定义了需求方法的常见行为。在这种情况下,使用动态分派。这意味着应该使用B中声明的实现。但问题的原因是多方面的

对于每种类型,Swift都使用见证表来注册用于动态分派的实现。该错误导致B类无法在协议的见证表中注册其update()的实现。当通过TheProtocol表发送更新时,使用了错误的实现

这里是您的示例,其中有一些更改。请注意,如果您在超类中声明update并在子类中重写它,它将按预期工作。这是我最清楚地看到虫子的方法

protocol TheProtocol {
    func update()
}

class A: TheProtocol {
    func update(){
        print("Implementation of A")
    }
}

class B : A {
    override func update(){
        print("Implementation of B")
    }
}

//All those who conform to TheProtocol will execute this.
extension TheProtocol {
    func update() {
        print("Common: TheProtocol")
    }
}
extension TheProtocol where Self: B {
    func update() {
        print("Common: TheProtocol for B's")
    }
}
extension TheProtocol where Self: A {
    func update() {
        print("Common: TheProtocol for A's")
    }
}


let instanceBViaProtocol:TheProtocol = B() //It prints "Implementation of B"
instanceBViaProtocol.update()
我希望这能回答你的问题

对swift中的方法分派有一个非常棒的解释


您可以阅读我在协议扩展中写的一篇关于方法分派的短文。

扩展协议Self:B{
更改为
扩展协议Self:a{
,看看它是否向您解释了一些内容。感谢您的提示。