表格总结如下:
- 值类型使用直接派发
- 协议、类的初始化声明使用函数表派发
- 协议、类的 extension 使用直接派发
- NSObject 类初始化声明也是函数表派发
- NSObject 类 extension 使用消息机制派发
题目
- 大家请看下面这段代码的答案是啥
protocol Drawing {
func render()
}
extension Drawing {
func circle() { p rint("protocol")}
func render() { circle()}
}
class SVG: Drawing {
func circle(){ print("class") }
}
SVG().render()
// what's the output?
答案是 "protocol"。 protocol 的 extension 中声明的方法是直接派发,编译的时候就已经确定了调用地址,类无法重写实现
protocol SeaFood {
}
extension SeaFood {
func makeFood() {
print("seaFood makeFood")
}
}
struct Person: SeaFood {
func makeFood() {
print("person makeFood")
}
}
let a: SeaFood = Person()
let b: Person = Person()
a.makeFood()
b.makeFood()
答案:a.makeFood()
为 seaFood makeFood,b.makeFood()
为 person makeFood。makeFood()
在 protocol extension 声明,是直接派发,编译期确定函数指针。a、b 声明是什么,就是什么。
如果更改上述代码为
protocol SeaFood {
func makeFood()
}
extension SeaFood {
func makeFood() {
print("seaFood makeFood")
}
}
struct Person: SeaFood {
func makeFood() {
print("person makeFood")
}
}
let a: SeaFood = Person()
let b: Person = Person()
a.makeFood()
b.makeFood()
答案:均输出 person makeFood。makeFood()
在 protocol 中声明,为函数表派发,运行时确定函数的指针,最终 a、b是什么,才是什么
网友评论