Swift 多态实现探究

多态

父类指针指向子类对象

  • Swift 中多态的实现类似于 c++ 中的虚表
  • OC 多态实现利用的是 Runtime

struct 与 class 调用函数的差异

从汇编看出,struct实例调用的函数都均在代码区的固定位置


class实例调用函数代码位置不固定,在方框处 si 进入,可以看到对应的是 animal.speck函数


汇编分析

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
  • 从汇编中可以看到一共调用了三个不确定位置的函数,分别是 callq *0x50(%rax)callq *0x58(%rax)callq *0x60(%rax),分别对应 speck、eat、sleep

  • 倒推发现,callq 所依赖的 rax 是 animal 的指针,指向的是所申请的堆空间对象。通过堆空间地址 + 固定偏移量来找到对应函数。


  • 多态的实现:将要调用父类还是子类的对应函数,这些信息都在编译时确定,保存于对象的类型信息中,位于全局区,调用时底层会去查询。

  • 同类对象的类型信息是同一块。


你可能感兴趣的:(Swift 多态实现探究)