引用类型 (Reference Type Matters)、扩展与派发方式
引用类型 (Reference Type Matters)
引用的类型决定了派发的方式. 这很显而易见, 但也是决定性的差异. 一个比较常见的疑惑, 发生在一个协议拓展和类型拓展同时实现了同一个函数的时候.
protocol MyProtocol {
}
struct MyStruct: MyProtocol {
}
extension MyStruct {
func extensionMethod() {
print("结构体")
}
}
extension MyProtocol {
func extensionMethod() {
print("协议")
}
}
let myStruct = MyStruct()
let proto: MyProtocol = myStruct
myStruct.extensionMethod() // -> “结构体”
proto.extensionMethod() // -> “协议”
刚接触 Swift 的人可能会认为 proto.extensionMethod()
调用的是结构体里的实现. 但是, 引用的类型决定了派发的方式, 协议拓展里的函数会使用直接调用. 如果把 extensionMethod
的声明移动到协议的声明位置的话, 则会使用函数表派发, 最终就会调用结构体里的实现. 并且要记得, 如果两种声明方式都使用了直接派发的话, 基于直接派发的运作方式, 我们不可能实现预想的 override
行为. 这对于很多从 Objective-C 过渡过来的开发者是反直觉的.
作者:kemchenj
链接:https://www.jianshu.com/p/91bfe3f11eec
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
我思故我在