Swift方法调度之类的普通方法底层探究

 更新时间:2021年11月01日 11:01:26   作者:一眼万年的星空  
这篇文章主要介绍了Swift-方法调度-类的普通方法底层探究,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

1. 类的普通方法调度

写一个结构体和一个类,对比看看方法调用的方式:

// 结构体
struct PersonStruct {
    func changClassName() {}
}
 
let s = PersonStruct()
s.changClassName()
 
// 类
class PersonClass {
    func changClassName() {}
}
 
let c = PersonClass()
c.changClassName()

生成 SIL 代码:

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

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

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

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

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

由上面 SIL 代码,我们可以看出,SIL 为类的方法创建了 sil_vtable,并在调用时,用class_method来修饰。这样的类的方法调度,是Swift 中动态派发的一种方式,叫做函数派发。

这里由sil_vtable关键字声明的就是函数表。函数表初始化的源码如下:

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

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

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

假设A类继承B类,B类继承C类,如下图所示:

3. 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() {}
}

到这里,证实2件事情:

  • Swift的函数表是按顺序存放的
  • 在类的继承关系中,函数表中存放所有的方法,由上到下,依次排列,先是父类的方法,再是子类的方法。

到此这篇关于Swift-方法调度-类的普通方法底层探究的文章就介绍到这了,更多相关Swift-方法调度内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 在 Swift 中编写Git Hooks脚本的方法

    在 Swift 中编写Git Hooks脚本的方法

    在本例中,我使用了 commit-msg 钩子,它能够在当前提交信息生效前修改此信息,钩子由一个参数调用,该参数是指向包含用户输入的提交消息的文件的路径,这意味着,为了改变提交消息,我们只需要从文件中读取、修改其内容,然后写回调用挂钩的文件
    2022-06-06
  • Swift语言中的一些访问控制设置详解

    Swift语言中的一些访问控制设置详解

    这篇文章主要介绍了Swift语言中的一些访问控制设置详解,是Swift入门学习中的基础知识,需要的朋友可以参考下
    2015-11-11
  • swift3.0指纹解锁的实现方法

    swift3.0指纹解锁的实现方法

    这篇文章主要为大家详细介绍了swift3.0指纹解锁的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-03-03
  • swift guard关键字详解及使用

    swift guard关键字详解及使用

    这篇文章主要介绍了swift guard关键字详解及使用的相关资料,需要的朋友可以参考下
    2017-06-06
  • Swift的函数式编程详解

    Swift的函数式编程详解

    这篇文章主要介绍了Swift的函数式编程详解,本文讲解了Swift概览、Swift递归、Swift 的高阶函数和闭包等内容,需要的朋友可以参考下
    2015-01-01
  • Swift面试题及答案整理

    Swift面试题及答案整理

    虽然Swift出现的时间不久,但是它已经成为最流行的编程语言之一了。Swift的知识浩如烟海,但是怎么测试你掌握了多少?通过下面这篇整理关于Swift面试题及答案,可能会对你所掌握的Swift进行一个判断,需要的朋友可以参考借鉴。
    2017-01-01
  • 详解Swift中的Characters字符类型与String字符串类型

    详解Swift中的Characters字符类型与String字符串类型

    Swift中的字符串操作相当便捷,下面我们来详解Swift中的Characters字符类型与String字符串类型,需要的朋友可以参考下
    2016-06-06
  • 详解Swift中的下标访问用法

    详解Swift中的下标访问用法

    在Swift中我们可以用subscript函数来定义下标,从而通过下标来访问数组与字典等数据结构,这里我们就来详解Swift中的下标访问用法:
    2016-07-07
  • SwiftUI学习之state和Binding的区别浅析

    SwiftUI学习之state和Binding的区别浅析

    这篇文章主要给大家介绍了关于SwiftUI学习之state和Binding区别的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • 如何在Swift 中使用 async let 并发运行后台任务

    如何在Swift 中使用 async let 并发运行后台任务

    Swift 异步编程是一种编写允许某些任务并发运行而不是按顺序运行的代码的方法,这篇文章主要介绍了在Swift中使用async let并发运行后台任务,需要的朋友可以参考下
    2023-06-06

最新评论