当前位置:网站首页>Swift运行时(派发机制)
Swift运行时(派发机制)
2022-08-02 02:23:00 【~废弃回忆 �༄】
消息的三种派发机制
直接派发(Direct Dispatch)
- 直接派发是最快的,不止是因为需要调用的指令集会更少,并且编译器还能够有很大的优化空间,例如函数内联等,直接派发也有人称为静态调用。
- 然而,对于编程来说直接调用也是最大的局限,而且因为缺乏动态性所以没办法支持继承和多态。
函数表派发(Table Dispatch)
- 函数表派发是编译型语言实现动态行为最常见的实现方式函数表使用了一个数组来存储类声明的每一个函数的指针.大部分语言把这个称为virtual table"虚函数表), Swift里称为“witness table.每一个类都会维护一个函数表,里面记录着类所有的函数,如果父类函数被 override的话,表里面只会保存被 override之后的函数.一个子类新添加的函数,都会被插入到这个数组的最后运行时会根据这一个表去决定实际要被调用的函数
- 查表是一种简单,易实现,而且性能可预知的方式.然而,这种派发方式比起直接派发还是慢一点从字节码角度来看,多了两次读和一次跳转,由此带来了性能的损耗.另一个慢的原因在于编译器可能会由于函数内执行的任务导致无法优化(如果函数带有副作用的话)
- 这种基于数组的实现,缺陷在于函数表无法拓展.子类会在虚数函数表的最后插入新的函数,没有位置可以让 extension安全地插入函数.
消息机制派发(Message Dispatch)
- 消息机制是调用函数最动态的方式.也是Ccoa的基石,这样的机制催生了kvo, UIAppearence和 CoreData等功能.这种运作方式的关键在于开发者可以在运行时改变函数的行为.不止可以通过 swizzling来改变,甚至可以用 isa-swizzling修改对象的继承关系可以在面向对象的基础上实现自定义派发.
Swift运行时
- 纯 Swift类的函数调用已经不再是 Objective-c的行时发消息,而是类似C++的vtable,在编译时就确定了调用哪个函数,所以没法通过 runtime获取方法、属性。
- 而Swift为了兼容 Objective-C,凡是继承自 NSObjec的类都会保留其动态性,所以我们能通过 runtime拿到他的方法。这里有一点说明:老版本的 Swift(如2.2)是编译期隐式的自动帮你加上了@objc,而40以后版本的 Swift编译期去掉了隐式特性,必须使用显式添加。
- 不管是纯Swift类还是继承自 NSObject的类只要在属性和方法前面添加@objc关键字就可以使用 runtime.
项目 | 原始定义 | 扩展 |
---|---|---|
值类型 | 直接派发 | 直接派发 |
协议 | 函数表派发 | 直接派发 |
类 | 函数表派发 | 直接派发 |
继承自NSObject的类 | 函数表派发 | 消息机制派发 |
小结
- 值类型总是会使用直接派发,简单易懂
- 而协议和类的 extension都会使用直接派发
- NSObject的 extension会使用消息机制进行派发
- NSObject声明作用域里的函数都会使用函数表进行派发.
- 协议里声明的,并且带有默认实现的函数会使用函数表进行派发
一些关键字的派发机制
关键字 | 机制 |
---|---|
final | 直接派发 |
dynamic | 消息机制派发 |
@objc & @nonobjc | 改变在OC里的可见性 |
@inline | 告诉编译器可以直接派发 |
Swift 运行时-final @objc
- 可以在标记为 final的同时,也使用@objc让函数可以使用消息机制派发.这么做的结果就是,调用函数的时候会使用直接派发,但也会在 Objective-c的运行时里注册响应的 selector.函数可以响应 perform(selector)以及别的 Objective-C特性但在直接调用时又可以有直接派发的性能.
边栏推荐
- 60 Feature Engineering Operations: Using Custom Aggregate Functions【Favorites】
- Project Background Technology Express
- 一次SQL优化,数据库查询速度提升 60 倍
- 永磁同步电机36问(二)——机械量与电物理量如何转化?
- Unable to log in to the Westward Journey
- 局部敏感哈希:如何在常数时间内搜索Embedding最近邻
- 极大似然估计
- Install mysql using docker
- 【LeetCode每日一题】——704.二分查找
- Win Go development kit installation configuration, GoLand configuration
猜你喜欢
局部敏感哈希:如何在常数时间内搜索Embedding最近邻
【 wheeled odometer 】
Nanoprobes丨1-巯基-(三甘醇)甲醚功能化金纳米颗粒
【web】Understanding Cookie and Session Mechanism
ofstream,ifstream,fstream read and write files
2022河南青训联赛第(三)场
[Server data recovery] Data recovery case of server Raid5 array mdisk disk offline
四元数、罗德里格斯公式、欧拉角、旋转矩阵推导和资料
Software testing Interface automation testing Pytest framework encapsulates requests library Encapsulates unified request and multiple base path processing Interface association encapsulation Test cas
"NetEase Internship" Weekly Diary (1)
随机推荐
个人博客系统项目测试
EFCore 反向工程
Lombok
Entry name 'org/apache/commons/codec/language/bm/gen_approx_greeklatin.txt' collided
Hash collisions and consistent hashing
2022年NPDP考完多久出成绩?怎么查询?
2022-07-30 mysql8 executes slow SQL-Q17 analysis
From 2023 onwards, these regions will be able to obtain a certificate with a score lower than 45 in the soft examination.
Handwriting a blogging platform ~ the first day
Project Background Technology Express
数值积分方法:欧拉积分、中点积分和龙格-库塔法积分
Simple example of libcurl accessing url saved as file
BI - SQL 丨 WHILE
FOFAHUB使用测试
Centos7 install postgresql and enable remote access
局部敏感哈希:如何在常数时间内搜索Embedding最近邻
Remember a gorm transaction and debug to solve mysql deadlock
leetcode / anagram in string - some permutation of s1 string is a substring of s2
LeetCode 213. Robbery II (2022.08.01)
libcurl访问url保存为文件的简单示例