Swift-多態(tài)的底層實(shí)現(xiàn)

問題1:什么是多態(tài)?

指允許不同類的對(duì)象對(duì)同一消息做出響應(yīng)。即同一消息可以根據(jù)發(fā)送對(duì)象的不同而采用多種不同的行為方式。(發(fā)送消息就是函數(shù)調(diào)用)實(shí)現(xiàn)多態(tài)的技術(shù)稱為:動(dòng)態(tài)綁定(dynamic binding),是指在執(zhí)行期間判斷所引用對(duì)象的實(shí)際類型,根據(jù)其實(shí)際的類型調(diào)用其相應(yīng)的方法。

問題2:swift 是怎樣表示多態(tài)的?

子類重寫父類的方法,使用父類聲明的變量分別創(chuàng)建子類和父類的對(duì)象,并使用變量調(diào)用相同的函數(shù)。

//基類
class Animal {
    func speak() {
        print("Animal - Speak")
    }

    func see() {
        print("Animal - see")
    }

    func sleep() {
        print("Animal - sleep")
    }
}
//子類繼承父類
class Dog: Animal {
  //重寫父類的speak,see函數(shù)
    override func speak() {
         print("Dog - Speak")
    }

    override func see() {
        print("Dog - see")
    }

    func run(){
        print("Dog - run")
    }
}

//定義一個(gè)變量
var animal: Animal

//創(chuàng)建Animal的對(duì)象,賦值給animal
animal = Animal()
//基類調(diào)用seapk,see,sleep函數(shù)
animal.speak()
animal.see()
animal.sleep()

//創(chuàng)建Dog的對(duì)象,也賦值給animal
animal = Dog()
//子類也調(diào)用seapk,see,sleep函數(shù)
animal.speak()
animal.see()
animal.sleep()

打印結(jié)果

Animal - Speak
Animal - see
Animal - sleep
Dog - Speak
Dog - see
Animal - sleep

根據(jù)對(duì)象不同,執(zhí)行不同的函數(shù)。

問題3:swfit底層是怎么通過對(duì)象調(diào)用函數(shù)的?

使用xcode查看匯編代碼,調(diào)用speak函數(shù)主要匯編代碼如下:

![tmp2e8ebba3.png](https://upload-images.jianshu.io/upload_images/1605700-36e81a7bbd668102.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

分析:
1.找到關(guān)鍵性匯編指令callq 調(diào)用函數(shù)。*0x50(%rcx),指將rcx的值加上0x50以后取出8個(gè)字節(jié)的內(nèi)容。rcx存儲(chǔ)的是類型信息,根據(jù)類型信息偏移x50找到函數(shù)speak并調(diào)用。

2.取出寄存器%rax里面存儲(chǔ)8個(gè)字節(jié)賦值給寄存器%rcx。獲取寄存器rax前八個(gè)字節(jié)的地址值并取出改地址值存儲(chǔ)的內(nèi)容,賦值給rcx。這時(shí)的rcx存儲(chǔ)的是Animal類型信息。

3.將0x23cc(%rip)里面內(nèi)存的8個(gè)字節(jié)給寄存器%rcx,這里看注釋,0x23cc(%rip)就應(yīng)該為變量animal,找到animal變量取出變量存儲(chǔ)的堆空間地址賦值給寄存器%rax。

tmp4772c205.png

tmp2018b686.png
tmp2e8ebba3.png

總結(jié):

通過指針變量尋找對(duì)象的堆空間,在根據(jù)堆空間的前8個(gè)字節(jié)存儲(chǔ)的指針查找類型信息的內(nèi)存地址,從類型信息偏移獲取對(duì)象函數(shù)地址值并進(jìn)行調(diào)用。
多態(tài)的實(shí)現(xiàn)是根據(jù)對(duì)象的堆空間查找前8個(gè)字節(jié)的類型信息,不同類型信息是不相同的,每個(gè)函數(shù)都一個(gè)函數(shù)地址,這個(gè)函數(shù)地址在編譯的時(shí)候就確認(rèn)并存儲(chǔ)到類型信息里面。過程就是指針->堆空間->類型信息->地址偏移。

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

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

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