zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    手机端适配rem代码片段
    location记录<18.7.21>
    本地储存(localStorage)记录
    为什么size_t重要?(Why size_t matters)(转)
    Mac OS X 完全卸载MySQL
    ECMAScript6兼容性
    mac截屏
    javascript中array的map方法的使用
    Jquery对话框基本配置
    angular中封装fancyBox(图片预览)
  • 原文地址:https://www.cnblogs.com/feng9exe/p/9674717.html
Copyright © 2011-2022 走看看