多態(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ì)去查詢。
-
同類對象的類型信息是同一塊。


