class Base { func show1() { } } extension Base { func show2() { } } class AA: Base { override func show2() { } } extension AA { override func show1() { } } 复制代码
当AA类的extension 重写 父类 Base 中的 show1 方法 或者 AA类在主体重写父类extension中的show2方法的时候, 编译器会提示错误 Overriding non-@objc declarations from extensions is not supported。swift
正确写法数组
class Base { @objc dynamic func show1() { } } extension Base { @objc func show2() { } } class AA: Base { override func show2() { } } extension AA { override func show1() { } } 复制代码
若是主体方法加上 @objc dynamic 子类的extension 就能够重写了。缓存
父类的extension中的方法加 @objc 子类的主体就能够重写了。markdown
Swift 目前方法调度 分为三种调度 直接调度,表调度,消息调度ide
直接调用方法声明 速度最快。可是不能动态的支持子类函数
通常用函数地址的数组来储存类中方法的声明spa
子类中Vtable 会添加父类的方法声明。code
OC 语言 就是采用这种方法调度的。经过msg_send() 方法来从类中或者父类中查询方法。这个调度比较慢,可是有缓存机制。能够提高效率。具备很好的灵活性。orm
Swift对应调度表对象
对象 | Static | VTable | Witness Table | Message |
---|---|---|---|---|
Swift struct | 默认行为 | N/A | : protocol | N/A |
Swift Class | final extension | 默认行为 | : protocol | dynamic |
继承NSObject | final extension | 默认行为 | : protocol | dynamic |
Protocol | extension | 默认行为 | N/A | : NSObjectProtocol @objc |
extension 中的方法默认是直接调度。
经过方法调度方式能够知道。
直接调度是不能被继承的。
表调度只能被子类主体继承。
那么若是要实现开头的方法重写 只有让方法是消息调度。
经过 在主体方法 加 @objc dynamic 关键字 和 extension 方法中添加 @objc,来改变方法的调度为消息调度。