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. (5)java Spring Cloud+Spring boot+mybatis企业快速开发架构之SpringCloud-Spring Boot简介

    ​Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是简化新 Spring 应用的初始搭建以及开发过程.该框架使用了特定的方式进行配置,从而使开发人员不再需要定义样板化的配置 ...

  2. servlet请求转发于重定向

    请求的转发与重定向是Servlet控制页面跳转的主要方法,在Web应用中使用非常广泛. 一. 请求的转发 Servlet接收到浏览器端请求后,进行一定的处理,先不进行响应,而是在服务器端内部" ...

  3. RocketMQ详解(二)安装使用详解

    专题目录 RocketMQ详解(一)原理概览 RocketMQ详解(二)安装使用详解 RocketMQ详解(三)启动运行原理 RocketMQ详解(四)核心设计原理 RocketMQ详解(五)总结提高 ...

  4. 深入xLua实现原理之Lua如何调用C#

    xLua是腾讯的一个开源项目,为Unity. .Net. Mono等C#环境增加Lua脚本编程的能力.本文主要是探讨xLua下Lua调用C#的实现原理. Lua与C#数据通信机制 无论是Lua调用C# ...

  5. 痞子衡嵌入式:嵌入式Cortex-M中断向量表对齐原则的深入研究

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是Cortex-M中断向量表对齐原则. 今天这篇文章的内容主要来自于五年前做 Kinetis K32W 系列双核启动时的发现,最近正好有同 ...

  6. CDI Features inJavaEE 的上下文和依赖注入

    基本的CDI的功能: 类型安全:CDI使用Java类型来解析注入,而不是通过(字符串)名称注入对象.当类型不足时, 可以使用限定符 注释.这允许编译器轻松检测错误,并提供简单的重构. POJO:几乎每 ...

  7. PHP中比较数组的时候发生了什么?

    首先还是从代码来看,我们通过比较运算符号来对两个数组进行比较: var_dump([1, 2] == [2, 1]); // false var_dump([1, 2, 3] > [3, 2, ...

  8. 什么是云效 Projex,云效Projex企业级高效研发项目管理平台

    云效项目协作Projects是一款企业级高效研发项目管理平台, 提供了快速实践的敏捷研发项目管理机制,提供对需求.迭代.缺陷各个维度的协同管理以及相关的统计报告,让研发团队高效协作.践行敏捷并持续交付 ...

  9. Jmeter系列(17)- 常用断言之JSON断言

    模块分析 Assert JSON Path exists:需要断言的 JSON 表达式 Additionally assert value:如果要根据值去断言,请勾选 Match as regular ...

  10. Linux系列(14) - grep

    简述 grep是在文件当中匹配符合条件的字符串,作用是查找文件内容 格式 grep [选项] 字符串 文件名 选项 -i:忽略大小写 -v:排除指定字符串 -n:显示行号 例子 grep " ...