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

  • 相关阅读:
    7年点工,中年测试人的出路与未来
    通过 jmeter 完成对请求字段的加密
    作为职场萌新怎么才能脱颖而出?
    阿里淘宝的 S1 级别 bug,到底是谁的锅?
    年前,我偷偷背着家人辞职,报名了软件测试
    一文搞定所有 web 自动化常见问题
    利用Android中DDMS->Heap工具检测内存泄漏问题
    Android Studio中怎么使用DDMS工具?
    使用DDMS测试安卓手机APP的性能(android)------转载
    web功能测试之表单、搜索测试
  • 原文地址:https://www.cnblogs.com/feng9exe/p/9674717.html
Copyright © 2011-2022 走看看