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,來改變方法的調度爲消息調度。