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. 设计模式-(7)桥接(swift版)

    一,概念 桥接模式为把抽象层次结构从实现中分离出来,使其可以独立变更,抽象层定义了供客户端使用的上层抽象接口,实现层次结构定义了供抽象层次使用的底层接口,实现类的引用被封装于抽象层的实例中,桥接就形成 ...

  2. mysql连接com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link

    jdbc驱动:mysql-connector-java-5.1.39-bin.jar 这个有问题, 换成:mysql-connector-java-5.1.34.jar 就可以了

  3. HDU2819 Swap —— 二分图最大匹配

    题目链接:https://vjudge.net/problem/HDU-2819 Swap Time Limit: 2000/1000 MS (Java/Others)    Memory Limit ...

  4. HDU1166 敌兵布阵 —— 线段树单点修改

    题目链接:https://vjudge.net/problem/HDU-1166 C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布 ...

  5. 修改eclipse启动程序超时时间

    修改workspace\.metadata\.plugins\org.eclipse.wst.server.core\servers.xml 把其中的start-timeout="45&qu ...

  6. UIBC 小註解(转载)

    转自:http://www.cash.idv.tw/wordpress/?p=7942 UIBC 是指 User Input Back Channel, 用在 WIFI Display 的情境之下. ...

  7. SpringBoot项目以服务器方式启动

    SpringBoot项目,如果未引入Web相关依赖,不会以服务器方式进行启动,会以应用的方式启动并结束 <dependency> <groupId>org.springfram ...

  8. Node 基本使用

    node -v:查看node版本 npm -v:查看npm版本 npm install npm -g :升级npm版本 npm install <module_name> [-g]:安装指 ...

  9. python爬取网页图片(二)

    从一个网页爬取图片已经解决,现在想要把这个用户发的图片全部爬取. 首先:先找到这个用户的发帖页面: http://www.acfun.cn/u/1094623.aspx#page=1 然后从这个页面中 ...

  10. 水题 Gym 100553K Knockout Racing

    题目传送门 /* 题意:有若干个点在一个区间内来回移动,1m/s. 水题:n^2的复杂度能解决,注意时间可能大于一个周期,要取模 */ #include <cstdio> #include ...