美文网首页
iOS Swift方法调度—类的普通方法

iOS Swift方法调度—类的普通方法

作者: 一眼万年的星空 | 来源:发表于2021-10-31 16:32 被阅读0次

类的普通方法调度

写一个结构体和一个类,对比看看:

// 结构体
struct PersonStruct {
    func changClassName() {}
}

let s = PersonStruct()
s.changClassName()

// 类
class PersonClass {
    func changClassName() {}
}

let c = PersonClass()
c.changClassName()

生成 SIL 代码:

【1】结构体及类的 SIL 代码:

Swift SIL 代码

与结构体不同的是:为PersonClass类自动生成了一个反初始化方法。

【2】执行方法的 SIL 代码:

Swift SIL 代码

在调用的方式中,可以看到类的方法,不是由function_ref 修饰,而是class_method修饰。

【3】还有一个不同点是,SIL 中为 PersonClass 自动生成了sil_vtable:

Swift SIL 代码

由上面 SIL 代码,我们可以看出,SIL 为类的方法创建了 sil_vtable,并在调用时,用class_method来修饰。这样的类的方法调度,是Swift 中动态派发的一种方式,叫做函数派发。
这里由sil_vtable 关键字声明的就是函数表。 函数表初始化的源码如下:

Swift SIL 代码

从源码中看,函数表中的数据结构是一个数组,源码是以遍历的的方式去获取函数表内的函数的,所以函数表是按顺序存放类中可能是函数派发去执行的函数,但是不一定函数表内的函数都会被以函数派发的方式去调度。

OC 继承链中的方法列表存储结构

我们知道 OC 中的方法是消息派发的方式。 每个对象中都有一个 isa 指针,指向自己的类。类中存放着该类实现的方法列表。本类方法列表中存放着本类实现的方法及父类方法列表的指针。在消息派发时,会先查找本来的方法列表,如果没找到,再去查找父类的方法列表,以此类推,来寻找方法的实现。
假设A类继承B类,B类继承C类,如下图所示:

OC 继承链

Swift 继承链中的函数表存储结构

Swift 类中函数派发与消息派发类似, 所有类也会维护一个自己的函数表, 不同的是所有未被复写的父类所实现的函数地址都会拷贝在这个表中, 而不是由一个指向父类方法表的指针替代, 被重写的函数,在函数表中会指定为子类中的函数。由于少了一步指针寻址步骤, 在派发效率上要比基于消息的派发高效。
假设A类继承B类,B类继承C类,如下图所示:

Swift 继承链

代码验证:

class PersonClass: NSObject {
    override init() {
        super.init()
        @objc func changClassName7() {}
        dynamic func changClassName8() {}
    }
}

class PersonClassSub: PersonClass {
    func runSub() {}
    // 重写的函数,在函数表中会指定为子类中的函数
    override func changClassName7() {}
}

class PersonClassSubSub: PersonClassSub {
    func runSubSub() {}
}
Swift 继承链

总结

到这里,证实2件事情:
● Swift的函数表是按顺序存放的
● 在类的继承关系中,函数表中存放所有的方法,由上到下,依次排列,先是父类的方法,再是子类的方法。

好了,小编给大家整理的swift的结构体与类的方法调度,若有收获,就点个赞吧!

青山不改,绿水长流,后会有期,感谢每一位佳人的支持!

相关文章

  • iOS Swift方法调度—类的普通方法

    类的普通方法调度 写一个结构体和一个类,对比看看: 生成 SIL 代码: 【1】结构体及类的 SIL 代码: 与结...

  • Swift 类的方法调度

    作者:Bel李玉链接:https://juejin.cn/post/6922071349473050638[htt...

  • Swift 5.1 (11) - 方法

    级别: ★☆☆☆☆标签:「iOS」「Swift 5.1」「实例方法」「类方法」「mutating」作者: 沐灵洛审...

  • iOS Swift 异变方法、方法调度

    一、异变方法(关键字:mutating) 值类型的属性只有在添加 mutating 关键字时才能被自身实例方法修改...

  • iOS Swift结构体与类的方法调度

    前言 hello,小伙伴们:在忙碌中闲暇之余给大家聊聊swift的知识点,今天给大家带来的是swift中结构体与类...

  • swift方法

    oc中只有类可以定义方法,swift类/结构体/枚举都能定义方法 swift的类型方法类似oc的类方法 实例方法(...

  • iOS runtime swift swizzling

    iOS runtime swift中的Swizzling方法交换 背景知识 Swift 是一种强类型语言。即默认类...

  • OC和Swift混编遇到的一些小麻烦

    一. OC中调用swift类中的方法时,编译器有时找不到方法声明 OC调用swift类中的方法,swift类需要有...

  • Swift方法调度

    Struct: 在结构体中方法都是静态调用(直接调用),也就意味着在在编译连接完成之后当前这个函数的地址就已经确定...

  • Swift 方法调度

    在swift中方法调度分为两种,直接调用和查找调用struct结构体的方法调用方式为直接调用,直接调用函数地址cl...

网友评论

      本文标题:iOS Swift方法调度—类的普通方法

      本文链接:https://www.haomeiwen.com/subject/jqboaltx.html