Swift 多態(tài)實(shí)現(xiàn)探究

多態(tài)

父類指針指向子類對象

  • Swift 中多態(tài)的實(shí)現(xiàn)類似于 c++ 中的虛表
  • OC 多態(tài)實(shí)現(xiàn)利用的是 Runtime

struct 與 class 調(diào)用函數(shù)的差異

從匯編看出,struct實(shí)例調(diào)用的函數(shù)都均在代碼區(qū)的固定位置


class實(shí)例調(diào)用函數(shù)代碼位置不固定,在方框處 si 進(jìn)入,可以看到對應(yīng)的是 animal.speck函數(shù)


匯編分析

class Animal {
    func speak() { print("animal speak") }
    func eat() { print("animal run") }
    func sleep() { print("animal sleep") }
}

class Dog: Animal {
    override func speak() { print("dog speak") }
    override func eat() { print("dog run") }
    func run() { print("run") }
}

var animal: Animal
animal = Animal()
animal.speak()  // animal speak 
animal.eat()    // animal run
animal.sleep()  // animal sleep

animal = Dog()  
animal.speak()  // dog speak  
animal.eat()    // dog run
animal.sleep()  // animal sleep
  • 從匯編中可以看到一共調(diào)用了三個(gè)不確定位置的函數(shù),分別是 callq *0x50(%rax)、callq *0x58(%rax) 、callq *0x60(%rax),分別對應(yīng) speck、eat、sleep

  • 倒推發(fā)現(xiàn),callq 所依賴的 rax 是 animal 的指針,指向的是所申請的堆空間對象。通過堆空間地址 + 固定偏移量來找到對應(yīng)函數(shù)。


  • 多態(tài)的實(shí)現(xiàn):將要調(diào)用父類還是子類的對應(yīng)函數(shù),這些信息都在編譯時(shí)確定,保存于對象的類型信息中,位于全局區(qū),調(diào)用時(shí)底層會(huì)去查詢。

  • 同類對象的類型信息是同一塊。


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容