领略一下swift函数派发机制流程
函数派发
Swift中函数的派发机制有三种:静态派发,函数表派发,消息派发。
静态派发
静态派发是指在运行时不需要查表,直接跳转到方法进行执行。静态派发的性能也是最高的。c语言采用的是直接派发。
函数表派发
class类型采用函数表派发。当一个对象调用一个函数时,会从对象的头8字节找到该对象的元信息。从元信息的函数表中找到执行的函数地址,并执行函数。
对象的元信息会在编译时写入macho文件中。
class Animal {
func speak() {
print("Animal speak")
}
func eat() {
print("Animal eat")
}
func sleep() {
print("Animal sleep")
}
}
class Dog: Animal {
override func speak() {
print("Dog speak")
}
override func eat() {
print("Dog eat")
}
func run() {
print("Dog run")
}
}class Animal {
func speak() {
print("Animal speak")
}
func eat() {
print("Animal eat")
}
func sleep() {
print("Animal sleep")
}
}
class Dog: Animal {
override func speak() {
print("Dog speak")
}
override func eat() {
print("Dog eat")
}
func run() {
print("Dog run")
}
}
Dog继承于Animal。let dog: Dog = Dog()dog 变量指向Dog对象。Dog对象在堆内存中。Dog对象的前8字节存有Dog对象的元信息。Dog对象的元信息中有该类的函数指针表。Dog中override父类Animal的函数会替换掉父类的函数存于Dogd的函数指针中。
### 消息派发
继承于NSObject的采用的是消息派发。Swift可以通过dynamic修饰来支持消息派发机制。
函数派发场景分析
在选择派发方式时,在编译期间就能决定执行哪个函数就采用静态派发。需要在运行期间决定执行哪个函数的就需要用函数表派发或者消息派发。不具动态性的的场景默认采用静态派发,这样派发效率更高。
struct无法继承,也就不具有动态性,函数派发在编译期间就能确定。
class和协议的 extension无法被子类继承,函数派发在编译期间就能确定。
class和协议的初始化方法,因为绝大多数时候需要被override的,所以采用函数表派发。
class的其他方法,如果没有被override,一般是函数表派发,但编译器也可能优化成直接派发。
class的 @objcextension能够继承,函数派发在执行期决定,并且是采用的是消息派发。
不继承NSObject的纯Swift,@objc的extension,采用的消息派发有点迷。消息派发机制需要有Objective-C的运行时,不继承与NSObject能有运行时的信息吗。该类的对象,
class FunctionDispatchObject {
func test1() {
print("test1")
}
}
extension FunctionDispatchObject {
@objc public func test2() {
print("test2")
}
}
// test1采用函数表派发
// test2采用消息机制派发:test2虽然写在extension里,当家里@objc,具有了动态性,可以继承了。class FunctionDispatchObject {
func test1() {
print("test1")
}
}
extension FunctionDispatchObject {
@objc public func test2() {
print("test2")
}
}
// test1采用函数表派发
// test2采用消息机制派发:test2虽然写在extension里,当家里@objc,具有了动态性,可以继承了。
领略一下swift函数派发机制流程的更多相关文章
- 深入理解 Swift 派发机制
原文: Method Dispatch in Swift作者: Brain King译者: kemchenj 译者注: 之前看了很多关于 Swift 派发机制的内容, 但感觉没有一篇能够彻底讲清楚这件 ...
- swift派发机制的核心是确定一个函数能否进入动态派发列表
swift派发机制的核心是确定一个函数能否进入动态派发列表
- swift 该死的派发机制--待完成
swift 该死的派发机制 final static oc类型 多态类型 静态类型 动态函数 静态函数 nsobject: 1.缺省不再使用oc的动态派发机制: 2.可以使用nsobject暴露出来 ...
- swift 即使不使用oc的动态派发机制也应该借鉴isa类型识别机制
目前的消息派发机制真的很鸡肋. 简直是一堆狗屎. 类型信息中包含所有需要动态派发的函数:这个包含两类:类和protocol: 在编译时,首先搜索动态派发列表: 动态派发列表没有,在搜索静态派发列表: ...
- Swift的基本类型和流程控制
Swift 是一门静态的强类型语言.它以简单.干净.可读性好等特点著称. 1. 为什么是静态语言? 首先静态语言比之动态语言,更具有安全性.它不允许类型之间自动的进行转换,必须要显示的转换.Swif ...
- [置顶] Android源码分析-点击事件派发机制
转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/17339857 概述 一直想写篇关于Android事件派发机制的文章,却一直没 ...
- Swift 静态派发和动态派发
前言 方法是 Swift 中的一个重要概念,方法允许你把需要复用的代码封装进方法中,这样当你调用方法时,实际上你的想法是执行方法中的那些代码,方法的出现极大的提高了方法的复用性. Swift 工程的环 ...
- Android源码分析-点击事件派发机制
转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/17339857 概述 一直想写篇关于Android事件派发机制的文章,却一直没 ...
- zookeeper心跳机制流程梳理
zookeeper心跳机制流程梳理 Processor链Chain protected void setupRequestProcessors() { RequestProcessor finalPr ...
- Scala深入浅出实战经典-----002Scala函数定义、流程控制、异常处理入门实战
002-Scala函数定义.流程控制.异常处理入门实战 Scala函数定义 语句结束无分号 定义无参函数 def 函数名称(参数名称:参数类型)[:Unit=]{ 函数体 } 老师的代码 我的实际代码 ...
随机推荐
- [转帖]使用GCC编译器实测兆芯KX-U6780A的SPEC CPU2006成绩
https://baijiahao.baidu.com/s?id=1722775453962904303 兆芯KX-U6780A是一款8核2.7GHz的使用x86/AMD64指令集(架构)的国产C ...
- [转帖]kubelet 原理解析五: exec的背后
https://segmentfault.com/a/1190000022163850 概述 线上排查pod 问题一般有两种方式,kubectl log或者kubectl exec调试.如果你的 lo ...
- sass中使用穿透属性(deep)修改第三方组件样似
<el-form-item> <el-button class="save-btn" type="primary" @click=" ...
- python入门之后须掌握的知识点(模块化编程、时间模块)【一】
相关文章: 全网最详细超长python学习笔记.14章节知识点很全面十分详细,快速入门,只用看这一篇你就学会了! python入门合集: python快速入门[一]-----基础语法 python快速 ...
- C/C++ 实现常用的线程注入
各种API远程线程注入的方法,分别是 远程线程注入,普通消息钩子注入,全局消息钩子注入,APC应用层异步注入,ZwCreateThreadEx强力注入,纯汇编实现的线程注入等. 简单编写DLL文件: ...
- window下部署单机hadoop环境
window本地部署单机hadoop,修改配置文件和脚本如下,只记录关键配置和步骤,仅供参考 hadoop-2.6.5 spark-2.3.3 1.配置文件core-site.xml <conf ...
- Json Schema高性能.net实现库 LateApexEarlySpeed.Json.Schema - 直接从code生成json schema validator
LateApexEarlySpeed.Json.Schema - Json schema validator generation from code 除了用户手动传入标准的json schema来生 ...
- 深入浅出Java多线程(五):线程间通信
引言 大家好,我是你们的老伙计秀才!今天带来的是[深入浅出Java多线程]系列的第五篇内容:线程间通信.大家觉得有用请点赞,喜欢请关注!秀才在此谢过大家了!!! 在现代编程实践中,多线程技术是提高程序 ...
- Hive-服务启动和停止命令
1.启动命令 #!/bin/bash nohup hive --service metastore >> $HIVE_HOME/logs/metasotre.log 2>&1 ...
- win10 通过 ssh 连接云服务器失败 are too open. bad permissions.
最近突然想起了自己的学生机服务器,买来了吃灰很久了,拿出来捣鼓捣鼓 以前服务器装的 windows server,这次把它重装成了 CentOS 8.0,然后按官网步连接步骤骤一步一步尝试. 腾讯云官 ...