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的更多相关文章

  1. [转]Inside Swift

    原文地址:http://www.eswick.com/2014/06/inside-swift/   Inside Swift Swift is Apple's new programming lan ...

  2. swift中文文档- 类型转换

    未翻译完 待续(英语烂,求斧正) Type Casting 类型转换 Type casting is a way to check the type of an instance, and/or to ...

  3. iOS - Swift 与 C 语言交互编程

    前言 作为一种可与 Objective-C 相互调用的语言,Swift 也具有一些与 C 语言的类型和特性,如果你的代码有需要,Swift 也提供了和常见的 C 代码结构混合编程的编程方式. 1.基本 ...

  4. swift之函数式编程(四)

    文章内容来自<Functional Programing in Swift>,具体内容请到书中查阅 Map, Filter, Reduce Functions that take func ...

  5. 如何找出Xcode中不同版本Swift的路径

    我们知道Xcode中可能包含不知一个Swift的版本,那么我们如何找到它们对应的路径呢? 熟悉unix shell命令的童鞋都知道有一个find指令,在我们已知Xcode路径时,我们可以在其中找到Sw ...

  6. 使用swift语言进行IOS应用开发

    在Swift中能够直接使用Objective-C语言提供的api (包括系统框架与自己的定制代码),也能够在Objective-C中使用Swift提供的类和api ,还能够在一个工程中同时混合使用Sw ...

  7. Building gRPC Client iOS Swift Note Taking App

    gRPC is an universal remote procedure call framework developed by Google that has been gaining inter ...

  8. Swift 与 C 语言混合编程

    前言 作为一种可与 Objective-C 相互调用的语言,Swift 也具有一些与 C 语言的类型和特性,如果你的代码有需要,Swift 也提供了和常见的 C 代码结构混合编程的编程方式. 1.基本 ...

  9. Swift 里 Array (二)初始化

    init() 函数 在 Array 里 public init() { _buffer = _Buffer() } 以Buffer 是 _ContiguousArrayBuffer 为例. 即初始化了 ...

随机推荐

  1. 提高 Linux 上 socket 性能 加速网络应用程序的 4 种方法

    使用 Sockets API,我们可以开发客户机和服务器应用程序,它们可以在本地网络上进行通信,也可以通过 Internet 在全球范围内进行通信.与其他 API 一样,您可以通过一些方法使用 Soc ...

  2. UVA10600 ACM Contest and Blackout —— 次小生成树

    题目链接:https://vjudge.net/problem/UVA-10600 In order to prepare the “The First National ACM School Con ...

  3. POJ - 1422 Air Raid(DAG的最小路径覆盖数)

    1.一个有向无环图(DAG),M个点,K条有向边,求DAG的最小路径覆盖数 2.DAG的最小路径覆盖数=DAG图中的节点数-相应二分图中的最大匹配数 3. /* 顶点编号从0开始的 邻接矩阵(匈牙利算 ...

  4. 并不对劲的hdu4777

    Long long ago, there was an ancient rabbit kingdom in the forest. Every rabbit in this kingdom was n ...

  5. DTV 常用功能

    AVL/Audio Description(AD SWITCH)/HearingImpaired 文档来自:https://max.book118.com/html/2016/0706/4752022 ...

  6. Lightoj 1068(数位DP)

    求一段区间中被k整除,各个位数相加之和被k整除的数的个数. 这不是重点,重点是k太大了,最大值有10000,所以不能直接开那么大的数组. 仔细分析一下可以发现,由于数最大是2的31次方(2147483 ...

  7. 计算属性computed 与methods

    你可能已经注意到我们可以通过调用表达式中的 method 来达到同样的效果: <p>Reversed message: "{{ reversedMessage() }}" ...

  8. asp.net调用oracle存储过程

    oracle内的存储过程是通过游标返回结果集的 DataTable dt = new DataTable(); OracleParameter[] paras = ]; paras[] = new O ...

  9. Ruby自定义打印的字符串

    重要性就不说了,没了这个出点小bug都要查半天. def inspect()     return "要输出的字符串写在这里咯" end         实际代码 #------- ...

  10. bzoj 3609: [Heoi2014]人人尽说江南好【博弈论】

    参考:https://blog.csdn.net/Izumi_Hanako/article/details/80189596 胜负和操作次数有关,先手胜为奇,所以先手期望奇数后手期望偶数,最后一定能达 ...