Swift 方法重寫 原理

Swift 方法重寫 報錯 Overriding non-@objc declarations from extensions is not supported。
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,來改變方法的調度爲消息調度。

相關文章
相關標籤/搜索