Swift中的动态调度和协议

时间:2016-11-22 11:32:49

标签: swift swift-protocols dynamic-dispatch

考虑这个(相当繁琐)的代码:

class SCell : NSObject {}
class SHeader : NSObject {}

class Cell : SCell {}
class Header : SHeader {}
struct Model {}

protocol PA {
    typealias Ce = SCell
    typealias He = SHeader
    func doThis(cell : PA.Ce,header : PA.He)
}

extension PA {
     func doThis(cell : PA.Ce,header : PA.He) {
        print("A's implementation")
    }
}

protocol PB:PA {

}

extension PB {
    func doThis(cell : PA.Ce,header : PA.He) {
        print("B's implementation")
    }
}

class A  : PA {
    func doSomethingElse() {
        self.doThis(cell: Cell(), header: Header())
    }
}

class B : A,PB {

}

class C : B {}

let c = C()
c.doSomethingElse()

令我惊讶的是,这开始打印

  

" A&C的实施"

我期待它打印" B&C的实施"因为doThis(cell:header)被覆盖为PB默认实现的一部分。这令人惊讶地没有发生。

如果我这样做,更有趣的是:

class B: A,PB {
    override func doSomethingElse() {
        self.doThis(cell: Cell(), header: Header())
    }
}

它开始打印

  

B&C的实施

为什么会这样?

1 个答案:

答案 0 :(得分:1)

协议扩展不执行多态,因此在这种情况下,如果不需要它们,则不会动态调度它们。原因是协议可以通过类,结构和枚举来采用。

另一个原因是您在 PA 中为协议提供默认实施,因此 PB 只有在方法丢失时才会生效(其中不是因为它已在 PA 中定义。

您可以阅读有关此here的更多信息。