runtime-相关资料

255 阅读3分钟

runtime底层实现原理: blog.csdn.net/yahibo/arti…

runtime(一)------类结构,方法结构,方法缓存等: blog.csdn.net/liujingran_…

OC中Runtime方法缓存: www.jianshu.com/p/7cbd77e0a…

crash收集: www.jianshu.com/p/05aad21e3… blog.csdn.net/u013602835/… blog.csdn.net/weixin_3422…

swift runtime:www.jianshu.com/p/cfd56c76f…

swift 类的结构:www.jianshu.com/p/093457ec5…

swift 中类与结构体:www.sohu.com/a/615609825…

1、Swift 中的消息调用

Swift 中的消息调用是通过 运行时(runtime)实现的。运行时是指程序运行时所处的环境,它提供了许多在编译时无法确定的功能,例如动态分配内存、检查类型、调用方法等。

在 Swift 中,每个类都有一个名为 isa(instance specific attributes)的指针,指向该类的 元类(metaclass)。元类包含有关该类的信息,例如类名、方法列表、属性列表等。

当调用一个对象的方法时,编译器会生成以下汇编代码:

mov eax, [esp+4] ; 获取 self 指针
mov edx, [eax+0] ; 获取 isa 指针
mov ecx, [METHOD_ADDR] ; 获取方法地址
jmp ecx ; 调用方法

其中:

  • esp+4 是栈顶指针,指向 self 对象
  • eax 存储 self 指针
  • [eax+0] 获取 isa 指针
  • METHOD_ADDR 是方法地址
  • ecx 存储方法地址
  • jmp ecx 调用方法

在运行时,objc_msgSend 函数会根据 isa 指针找到要调用的方法。如果方法是 静态派发(static dispatch)的,则直接调用该方法。如果方法是 动态派发(dynamic dispatch)的,则需要根据对象的类型查找要调用的具体实现。

静态派发 是指在编译时就已经确定要调用的方法。例如,调用结构体或枚举类型的方法就是静态派发的。因为结构体和枚举类型的值类型,其类型在编译时就已经确定了。

动态派发 是指在运行时才确定要调用的方法。例如,调用类的方法就是动态派发的。因为类是引用类型,其类型的具体实现可能在运行时才知道。

Swift 中的动态派发是通过 虚函数表(virtual table)实现的。虚函数表是一个包含方法地址的表,每个类都有一个虚函数表。当调用一个类的方法时,objc_msgSend 函数会根据 isa 指针找到该类的虚函数表,然后根据方法选择器找到要调用的方法地址。

虚函数表使得 Swift 具有很强的灵活性,例如可以实现多态性。多态性是指同一方法可以根据不同的对象类型表现出不同的行为。例如,我们可以定义一个 Shape 类,并定义 draw() 方法。然后,我们可以创建 CircleRectangle 等子类,并重写 draw() 方法。这样,当调用 draw() 方法时,会根据实际调用该方法的对象类型调用不同的实现。

以下是 Swift 中消息调用的一个示例:

Swift

class Person {
    func sayHello() {
        print("Hello, world!")
    }
}

class Student: Person {
    override func sayHello() {
        print("Hello, world! I am a student.")
    }
}

let person = Person()
person.sayHello() // 输出:Hello, world!

let student = Student()
student.sayHello() // 输出:Hello, world! I am a student.

谨慎使用代码。

content_copy

在这个示例中,Person 类和 Student 类都定义了 sayHello() 方法。但是,Student 类重写了 sayHello() 方法。因此,当调用 person.sayHello() 时,会调用 Person 类的 sayHello() 实现。而当调用 student.sayHello() 时,会调用 Student 类的 sayHello() 实现。

总而言之,Swift 中的消息调用是通过运行时和虚函数表实现的。这使得 Swift 具有很强的灵活性,例如可以实现多态性。