• 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

  • 相关阅读:
    微信小程序【消息推送服务器认证C# WebAPI】
    bootstrap-table表格导出
    EntityFramework Code-First教程(一)
    Ubuntu 中的VI和vim
    【转载】Ubuntu安装之,硬盘分区
    ubuntu中文件夹的作用
    Linux常用命令
    详解Linux安装GCC
    修改Linux下的文件以及文件夹的权限
    Y460 安装ubuntu 12.04系统黑屏,登录界面黑屏
  • 原文地址:https://www.cnblogs.com/feng9exe/p/9674717.html
Copyright © 2020-2023  润新知