参考:http://www.jb51.cc/article/p-pjlxfjje-d.html
对于编译型的语言,函数派发的三种基础模式分别是:
- 直接派发(direct dispatch)(也可以理解外,直接调用 ,不需要曲线救国 )
- 函数表派发(table dispatch)(面向对象的语言中,一般都会有类的概念,类 用一个数组来存储类中的函数指针,通过此列表 去找 对应的函数)这种派发-》催生了 继承
- 消息派发(Message dispatch)消息机制是调用函数最动态的方式. 也是 Cocoa 的基石,这样的机制催生了 KVO,UIAppearence 和 CoreData 等功能. 这种运作方式的关键在于开发者可以在运行时改变函数的行为. 不止可以通过 swizzling 来改变,甚至可以用 isa-swizzling 修改对象的继承关系,可以在面向对象的基础上实现自定义派发.
重点: 在运行时 修改函数的行为
#### 三种、c类开销最大、a类开销最小; 想要更快的速度,我们肯定是减少 开销;
Swift 没有在文档里具体写明什么时候会使用函数表什么时候使用消息机制. 唯一的承诺是使用 dynamic 修饰的时候会通过 Objective-C 的运行时进行消息机制派发.
了解这些后,我们来看一下,swift 中的函数;
一、swift 中函数 的位置:
能够使用的位置;(换句话说,函数 能够定义在 类与扩展中)
a、类作用域
在类中,函数的派发机制一般为函数表机制,也可以加一些修饰符,来强制修改其派发机制;
b、扩展作用域
默认的直接派发;
c、在协议中可以申明函数,不实现
d 、在结构体中 :直接派发
swift 派发方式:
看一下下面这个例子
class A:NSObject{
//函数 sayhi() 会在 a 消息机制:加上 dynamic 强制为 消息机制发送
dynamic func sayhi() {
print("a-消息派发")
}
//函数 sayhi() 会在 a的函数表里找到
func sayhi1() {
print("a-函数派发")
}
}
func say(a:A){
a.sayhi()
a.sayhi1()
}
say(a: A())
//结果 1 这里没啥好说的,主要看下面的扩展,会发现很有意思的事
//a-消息派发
//a-函数派发
class B:A{
//函数 采用 函数表派发
}
extension B{
//消息派发
override func sayhi() {
print("b-重写 消息派发")
}
override func sayhi1() {
print("消息派发2")
}
}
say(a: B())
//结果:2
//b-重写 消息派发
//a-函数派发
在结果2中,我们发现 重写 message dispath的函数,可以执行; 重写 table dispatch 的函数,结果还是父类里面的内容; 在这里,这个就是由于 swift 派发机制 决定的,对于 b类里面,是继承nsobject ,派发是:消息机制,在a 类里默认是函数机制,所以这里 派发机制不统一,所以出现问题,所以, 这里解决方式: 1、将 重写方法 放类里面 2、加 dynamic 修饰符