swift class type isa-swizzling
class 是引用类型,生成的实例分布在 Heap(堆) 内存区域上,在 Stack(栈)只存放着一个指向堆中实例的指针。因为考虑到引用类型的动态性和 ARC 的原因,class 类型实例需要有一块单独区域存储类型信息和引用计数。
在 Swift 中,class 类型的方法派发是通过 V-Table 来实现动态派发的。Swift 会为每一种类类型生成一个 Type 信息并放在静态内存区域中,而每个类类型实例的 type 指针就指向静态内存区域中本类型的 Type 信息。当某个类实例调用方法的时候,首先会通过该实例的 type 指针找到该类型的 Type 信息,然后通过信息中的 V-Table 得到方法的地址,并跳转到相应的方法的实现地址去执行方法。
通过上面的分析,我们知道一个类类型的方法派发是通过头部的 type 指针来决定的,如果我们将某个类实例的 type 指针指向另一个 type 会不会有什么好玩的事情发生呢?哈哈 ~ 一起来试试 ~
class Wolf {
var name: String = "wolf"
func soul() {
print("my soul is wolf")
}
func headPointerOfClass() -> UnsafeMutablePointer<Int8> {
let opaquePointer = Unmanaged.passUnretained(self as AnyObject).toOpaque()
let mutableTypedPointer = opaquePointer.bindMemory(to: Int8.self, capacity: MemoryLayout<Wolf>.stride)
return UnsafeMutablePointer<Int8>(mutableTypedPointer)
}
}
class Fox {
var name: String = "fox"
func soul() {
print("my soul is fox")
}
func headPointerOfClass() -> UnsafeMutablePointer<Int8> {
let opaquePointer = Unmanaged.passUnretained(self as AnyObject).toOpaque()
let mutableTypedPointer = opaquePointer.bindMemory(to: Int8.self, capacity: MemoryLayout<Fox>.stride)
return UnsafeMutablePointer<Int8>(mutableTypedPointer)
}
}
let wolf = Wolf()
var wolfPtr = UnsafeMutableRawPointer(wolf.headPointerOfClass())
let fox = Fox()
var foxPtr = UnsafeMutableRawPointer(fox.headPointerOfClass())
foxPtr.advanced(by: 0).bindMemory(to: UnsafeMutablePointer<Wolf.Type>.self, capacity: 1).initialize(to: wolfPtr.advanced(by: 0).assumingMemoryBound(to: UnsafeMutablePointer<Wolf.Type>.self).pointee)
print(type(of: fox)) //Wolf
print(fox.name) //"fox"
fox.soul()
https://mp.weixin.qq.com/s/zIkB9KnAt1YPWGOOwyqY3Q
swift class type isa-swizzling的更多相关文章
- [转]Inside Swift
原文地址:http://www.eswick.com/2014/06/inside-swift/ Inside Swift Swift is Apple's new programming lan ...
- swift中文文档- 类型转换
未翻译完 待续(英语烂,求斧正) Type Casting 类型转换 Type casting is a way to check the type of an instance, and/or to ...
- iOS - Swift 与 C 语言交互编程
前言 作为一种可与 Objective-C 相互调用的语言,Swift 也具有一些与 C 语言的类型和特性,如果你的代码有需要,Swift 也提供了和常见的 C 代码结构混合编程的编程方式. 1.基本 ...
- swift之函数式编程(四)
文章内容来自<Functional Programing in Swift>,具体内容请到书中查阅 Map, Filter, Reduce Functions that take func ...
- 如何找出Xcode中不同版本Swift的路径
我们知道Xcode中可能包含不知一个Swift的版本,那么我们如何找到它们对应的路径呢? 熟悉unix shell命令的童鞋都知道有一个find指令,在我们已知Xcode路径时,我们可以在其中找到Sw ...
- 使用swift语言进行IOS应用开发
在Swift中能够直接使用Objective-C语言提供的api (包括系统框架与自己的定制代码),也能够在Objective-C中使用Swift提供的类和api ,还能够在一个工程中同时混合使用Sw ...
- Building gRPC Client iOS Swift Note Taking App
gRPC is an universal remote procedure call framework developed by Google that has been gaining inter ...
- Swift 与 C 语言混合编程
前言 作为一种可与 Objective-C 相互调用的语言,Swift 也具有一些与 C 语言的类型和特性,如果你的代码有需要,Swift 也提供了和常见的 C 代码结构混合编程的编程方式. 1.基本 ...
- Swift 里 Array (二)初始化
init() 函数 在 Array 里 public init() { _buffer = _Buffer() } 以Buffer 是 _ContiguousArrayBuffer 为例. 即初始化了 ...
随机推荐
- 提高 Linux 上 socket 性能 加速网络应用程序的 4 种方法
使用 Sockets API,我们可以开发客户机和服务器应用程序,它们可以在本地网络上进行通信,也可以通过 Internet 在全球范围内进行通信.与其他 API 一样,您可以通过一些方法使用 Soc ...
- UVA10600 ACM Contest and Blackout —— 次小生成树
题目链接:https://vjudge.net/problem/UVA-10600 In order to prepare the “The First National ACM School Con ...
- POJ - 1422 Air Raid(DAG的最小路径覆盖数)
1.一个有向无环图(DAG),M个点,K条有向边,求DAG的最小路径覆盖数 2.DAG的最小路径覆盖数=DAG图中的节点数-相应二分图中的最大匹配数 3. /* 顶点编号从0开始的 邻接矩阵(匈牙利算 ...
- 并不对劲的hdu4777
Long long ago, there was an ancient rabbit kingdom in the forest. Every rabbit in this kingdom was n ...
- DTV 常用功能
AVL/Audio Description(AD SWITCH)/HearingImpaired 文档来自:https://max.book118.com/html/2016/0706/4752022 ...
- Lightoj 1068(数位DP)
求一段区间中被k整除,各个位数相加之和被k整除的数的个数. 这不是重点,重点是k太大了,最大值有10000,所以不能直接开那么大的数组. 仔细分析一下可以发现,由于数最大是2的31次方(2147483 ...
- 计算属性computed 与methods
你可能已经注意到我们可以通过调用表达式中的 method 来达到同样的效果: <p>Reversed message: "{{ reversedMessage() }}" ...
- asp.net调用oracle存储过程
oracle内的存储过程是通过游标返回结果集的 DataTable dt = new DataTable(); OracleParameter[] paras = ]; paras[] = new O ...
- Ruby自定义打印的字符串
重要性就不说了,没了这个出点小bug都要查半天. def inspect() return "要输出的字符串写在这里咯" end 实际代码 #------- ...
- bzoj 3609: [Heoi2014]人人尽说江南好【博弈论】
参考:https://blog.csdn.net/Izumi_Hanako/article/details/80189596 胜负和操作次数有关,先手胜为奇,所以先手期望奇数后手期望偶数,最后一定能达 ...