Swift 静态派发和动态派发
前言
方法是 Swift 中的一个重要概念,方法允许你把需要复用的代码封装进方法中,这样当你调用方法时,实际上你的想法是执行方法中的那些代码,方法的出现极大的提高了方法的复用性。
Swift 工程的环境是非常复杂的,如何凭借方法的名字正确的找到方法中的代码实际上并不是听起来那样简单,在寻找代码的道路上又静态派发和动态派发两种不同的方式。
1、动态派发
OC 程序员应该不会对动态派发感到陌生,OC 中的方法都是动态派发的,也就是我们常说的消息转发。
动态派发是指需要在运行时找到方法的具体实现。
- Swift 中的动态派发和 OC 中的动态派发类似,在运行时程序会根据被调用的方法的名字去内存中的方法表中查表,找到方法的实现并执行。
- 虽然动态派发的执行效率不如静态派发高,但是在很多情况下动态派发是合理的,比如异构数组中的方法调用使用的就是动态派发,这是因为静态派发的设计哲学与异构数组的设计初衷在本质上是互斥的。
动态派发在编译时编译器不能知道某个方法的具体实现,这与方法调用时的上下文密切相关。
- 比如当对象的上下文是一个协议时,运行时传入的必须是协议的遵守者,而不同遵守者中的同一个方法会有多个版本的实现,由于这种方法实现的不确定性,编译器无法完成静态派发,所以需要在运行时通过判断实例的真实身份,找到与之匹配的代码并执行。
- 类似的还有父类与子类的情况。
多态是编程语言中 “不确定性” 的典型代表,动态派发机制为多态提供了支撑,在 Swift 中继承和协议都具有多态的特性。
2、静态派发
静态派发是指在运行时调用方法不需要查表,直接跳转到方法的代码中执行。
- 很显然静态派发是一种更高效的方法,因为静态派发免去了查表操作。
- 不过静态派发是有条件的,方法内部的代码必须对编译器透明,并且在运行时不能被更改,这样编译器才能帮助我们。
- Swift 中的值类型不能被继承,也就是说值类型的方法实现不能被修改或者被复写,因此值类型的方法满足静态派发的要求。
静态派发为 “内联” 或者其它优化提供了支持。
- 支持 “内联” 的方法要求方法本身必须是静态派发的。
- 不像 C 语言使用关键字
inline注明内联,Swift 中值类型的方法是默认执行内联的。 - 内联是指在编译期把每一处方法调用替换为直接执行方法内部的代码,可以帮助你避免运行时方法调用的时间开销。
Swift 静态派发和动态派发的更多相关文章
- swift protocol 见证容器 虚函数表 与 动态派发
一.测试代码: //protocol DiceGameDelegate: AnyObject { //} // //@objc protocol OcProtocol{ // @objc fun ...
- swift class的动态派发
一.测试代码 class BaseCallClass{ func NormalCall(){} @objc func OcCall(){} @objc dynamic func OcDynamicCa ...
- swift static与class修饰符:static不参与动态派发
static与class 都有类型成员的含义:相对于实例成员: static的另一个意思是静态派发:所以不能被继承. 要使用动态派发和继承的机制必须使用class继承. static的其它常见含义: ...
- swift派发机制的核心是确定一个函数能否进入动态派发列表
swift派发机制的核心是确定一个函数能否进入动态派发列表
- swift 即使不使用oc的动态派发机制也应该借鉴isa类型识别机制
目前的消息派发机制真的很鸡肋. 简直是一堆狗屎. 类型信息中包含所有需要动态派发的函数:这个包含两类:类和protocol: 在编译时,首先搜索动态派发列表: 动态派发列表没有,在搜索静态派发列表: ...
- iOS 静态库,动态库与 Framework 浅析
静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用. 什么时候我们会用到库呢?一种情况是某些代码需要给别人使用,但是我们不希望别人 ...
- iOS 静态库,动态库与 Framework
iOS 静态库,动态库与 Framework 静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用. 什么时候我们会用到库呢 ...
- Android GradientDrawable(shape标签定义) 静态使用和动态使用(圆角,渐变实现)
Android GradientDrawable使用优势: 1. 快速实现一些基本图形(线,矩形,圆,椭圆,圆环) 2. 快速实现一些圆角,渐变,阴影等效果 3. 代替图片设置为View的背景 4. ...
- C++ 系列:静态库与动态库
转载自http://www.cnblogs.com/skynet/p/3372855.html 这次分享的宗旨是——让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择 ...
随机推荐
- 诡异的楼梯 HDU1180
这题做了很久 做好了感觉很简单... 现在做题思路更加清晰了 一个要点就是 当楼梯过不去的时候不能是先过去时间加2 必须得回去等一秒 否则queue的时间顺序会被打破 #include< ...
- [OpenCV-Python] OpenCV 中图像特征提取与描述 部分 V (一)
部分 V图像特征提取与描述 OpenCV-Python 中文教程(搬运)目录 29 理解图像特征 目标本节我会试着帮你理解什么是图像特征,为什么图像特征很重要,为什么角点很重要等.29.1 解释 我相 ...
- laravel 控制器使用MODEL
第一步:引入MODEL类 use App\Http\Models\Sysdba; 第二步:使用 $uid = $request->input('uid'); 方法1. $model = new ...
- FastAdmin 在 Nginx 中的配置
FastAdmin 使用的是 ThinkPHP 5 框架. 在 Apache 下很简单,但是在 nginx 下就需要自行配置一下了. 在网上找了很多,都没有找到很好的. 刚刚在 QQ 里群里找到一个, ...
- VSCode从非根目录编译golang程序(转)
1.问题提出 “习惯在项目目录里建src放源码文件,根目录里放配置文件或者别的什么,在交付时直接忽视掉src目录就行了,但vscode好像不能这样愉快的玩耍...”??? 要实现把源码放到src目录下 ...
- HDU 2639 骨头收集者 II【01背包 】+【第K优决策】
题目链接:https://vjudge.net/contest/103424#problem/H 题目大意:与01背包模板题类似,只不过要我们求第K个最大的总价值. 解题分析: 其基本思想是将每个状态 ...
- js基础梳理-究竟什么是执行上下文栈(执行栈),执行上下文(可执行代码)?
日常在群里讨论一些概念性的问题,比如变量提升,作用域和闭包相关问题的时候,经常会听一些大佬们给别人解释的时候说执行上下文,调用上下文巴拉巴拉,总有点似懂非懂,不明觉厉的感觉.今天,就对这两个概念梳理一 ...
- grpc 使用流程、使用技巧
1.通过maven插件编译出java stub类. 2.对于批量调用的场景,我们可以使用FutureStub,对于普通的业务类型RPC,我们应该使用BlockingStub. 3.创建批量生成多个语言 ...
- LOJ.6062.[2017山东一轮集训]Pair(Hall定理 线段树)
题目链接 首先Bi之间的大小关系没用,先对它排序,假设从小到大排 那么每个Ai所能匹配的Bi就是一个B[]的后缀 把一个B[]后缀的匹配看做一条边的覆盖,设Xi为Bi被覆盖的次数 容易想到 对于每个i ...
- Flask的使用
一.路由系统 1.子域名的配置 """ 可传入的参数: @app.route('/user/<username>') @app.route('/post/&l ...