Swift 继承之方法重写
2022-02-21 本文已影响0人
yyggzc521
Swift 类继承时,需要方法重写,结果报错 :
Overriding non-@objc declarations from extensions is not supported
父类Base
class Base {
func show1() { }
}
extension Base {
func show2() { }
}
子类child
当子类child的extension 重写 父类 Base 中的 show1 方法 或者 重写父类extension中的show2方法时,就会报上面的错误!
class child: Base {
override func show2() { }
}
extension child {
override func show1() { }
}
正确写法
- 父类主体方法加上 @objc dynamic 子类的extension 就可以重写了。
- 父类extension方法加 @objc 子类的主体就可以重写了
class Base {
@objc dynamic func show1() { }
}
extension Base {
@objc func show2() { }
}
class child: Base {
override func show2() { }
}
extension child {
override func show1() { }
}
why?
Swift的方法调度分为 三种
- 直接调度
- 表调度
- 消息调度
- 直接调度:直接调用方法声明,速度最快。但是不能动态的支持子类
- 表调度:一般用函数地址的数组来储存类中方法的声明,子类中Vtable 会添加父类的方法声明
- 消息调度:OC语言就是采用这种方法调度的。通过msg_send() 方法来从类或者父类中查询方法。这个调度比较慢,但有缓存机制,可以提升效率,具有很好的灵活性。
extension 中的方法默认是直接调度,直接调度是不能被继承的。
表调度只能被子类主体继承。
那么如果要实现开头的方法重写 只有让方法是消息调度。
通过 在主体方法 加 @objc dynamic 关键字 和 extension 方法中添加 @objc,来改变方法的调度为消息调度。