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() { }
}

正确写法

  1. 父类主体方法加上 @objc dynamic 子类的extension 就可以重写了。
  2. 父类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的方法调度分为 三种

  1. 直接调度:直接调用方法声明,速度最快。但是不能动态的支持子类
  2. 表调度:一般用函数地址的数组来储存类中方法的声明,子类中Vtable 会添加父类的方法声明
  3. 消息调度:OC语言就是采用这种方法调度的。通过msg_send() 方法来从类或者父类中查询方法。这个调度比较慢,但有缓存机制,可以提升效率,具有很好的灵活性。
Swift对应调度表

extension 中的方法默认是直接调度,直接调度是不能被继承的。
表调度只能被子类主体继承。

那么如果要实现开头的方法重写 只有让方法是消息调度。
通过 在主体方法 加 @objc dynamic 关键字 和 extension 方法中添加 @objc,来改变方法的调度为消息调度。


参考文章

上一篇 下一篇

猜你喜欢

热点阅读