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-方法调度-类的普通方法底层探究的更多相关文章

  1. C#中如果类的扩展方法和类本身的方法签名相同,那么会优先调用类本身的方法

    新建一个.NET Core项目,假如我们有如下代码: using System; namespace MethodOverload { static class DemoExtension { pub ...

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

    前言 hello,小伙伴们:在忙碌中闲暇之余给大家聊聊swift的知识点,今天给大家带来的是swift中结构体与类的方法调度详细区别,希望对你有所帮助,好了废话不用多说,接下来步入主题! 1.普通方法 ...

  3. Java Native Interfce三在JNI中使用Java类的普通方法与变量

    本文是<The Java Native Interface Programmer's Guide and Specification>读书笔记 前面我们学习了如何在JNI中通过参数来使用J ...

  4. Eclipse_常用技巧_01_自动添加类注释和方法注释

    一.步骤 路径A=windows-->preference-->Java-->Code Style-->Code Templates-->Comments 自动添加注释一 ...

  5. Math类的random()方法

    Math类的random()方法 Math类的random()方法可以生成大于等于0.0.小于1.0的double型随机数. Math.random()方法语句基础上处理可获得多种类型.或任意范围的随 ...

  6. Swift进阶之内存模型和方法调度

    前言 Apple今年推出了Swift3.0,较2.3来说,3.0是一次重大的升级.关于这次更新,在这里都可以找到,最主要的还是提高了Swift的性能,优化了Swift API的设计(命名)规范. 前段 ...

  7. swift 笔记 (十一) —— 方法(类,结构体,枚举)

    Methods (方法) 实例方法(Instance Methods) 我认为看到这里.我们唯能八一八的就是swift的自做主张的行为了,反正它就是会以各种方式帮助我们来完毕让代码看起来非常奇怪的事情 ...

  8. swift -- 类中的方法

    一. 引用类型  类 在类中定义方法 class Person { //属性 var name : String = "" //方法 //实例方法 : 在类里面创建一个方法 fun ...

  9. Java学习笔记之方法重载,动态方法调度和抽象类

    一.方法重载 如果子类中的方法与它的超类中的方法有相同的方法名,则称子类中的方法重载超类中的方法,特别是当超类和子类中的方法名和参数类型都相同时,在子类中调用该方法时,超类中的方法会被隐藏.考虑下面程 ...

随机推荐

  1. 【第十九篇】- Maven NetBeans之Spring Cloud直播商城 b2b2c电子商务技术总结

    Maven NetBeans NetBeans 6.7 及更新的版本已经内置了 Maven.对于以前的版本,可在插件管理中心获取 Maven 插件.此例中我们使用的是 NetBeans 6.9. 关于 ...

  2. 详解JDBC中的Class.forName(DriverName)

    在Java开发特别是数据库开发中,经常会用到Class.forName( )这个方法.通过查询Java Documentation我们会发现使用Class.forName( )静态方法的目的是为了动态 ...

  3. html回车键搜索内容

    window.onkeydown = function(e){ // elsinput是搜索框 if(e.keyCode === 13 && elsinput.is(':focus') ...

  4. 一文让你彻底搞懂 vue-Router

    路由是网络工程里面的专业术语,就是通过互联把信息从源地址传输到目的地址的活动.本质上就是一种对应关系.分为前端路由和后端路由. 后端路由: URL 的请求地址与服务器上的资源对应,根据不同的请求地址返 ...

  5. python BeautifulSoup html解析

    * BeautifulSoup 的.find(), .findAll() 函数原型 findAll(tag, attributes, recursive, text, limit, keywords) ...

  6. 使用php函数 json_encode ,数据存入mysql

    $data = json_encode($array); // 过滤 $data = addslashes($data); // 插入数据库 $db->insert($table_name,ar ...

  7. 『Python』matplotlib共享绘图区域坐标轴

    1. 共享单一绘图区域的坐标轴 有时候,我们想将多张图形放在同一个绘图区域,不想在每个绘图区域只绘制一幅图形.这时候,就可以借助共享坐标轴的方法实现在一个绘图区域绘制多幅图形的目的. import n ...

  8. RabbitMQ3.9.7在CentOS7中的安装搭建

    1.概述 RabbitMQ 是目前很流行的消息中间件之一,可靠性非常好,能简单的实现高可用.负载均衡. 今天我们先来聊一下 RabbitMQ 3.9.7 版本在 CentOS7 中的安装. 2.安装R ...

  9. P6097-[模板]子集卷积

    正题 题目链接:https://www.luogu.com.cn/problem/P6097 题目大意 长度为\(2^n\)的序列\(a,b\)求一个\(c\)满足 \[c_k=\sum_{i|j=k ...

  10. Excel备忘录

    1. 导入文本文件(.txt) 2. 排序 3. 批量填充空白 选定区域,Ctrl+G,定位,空值. 输入内容,Ctrl+Enter. 4. 清除无法修改的背景色. 5. 身份证号 数字精度为15位, ...