美文网首页
对象的 isa 指针指向哪里?

对象的 isa 指针指向哪里?

作者: 游城十代2dai | 来源:发表于2020-04-06 13:31 被阅读0次
    1. instance 对象的 isa 指针指向 class, 当调用对象方法时, isa 找到 class, 然后找到相应方法进行调用
    2. class 对象的 isa 指针指向 meta-class, 当调用类方法时, isa 找到 meta-class, 然后找到相应方法进行调用
    3. meta-class 对象的 isa 指针指向基类的 meta-class, 基类的指向自己

    instance 对象调用流程: instance(subclass) 中的 isa 去 subclass 中找方法, 如果没找到就用 superclass 指针找到 subclass 的父类 superclass, 如果还没有就继续递进到 rootclass 中查找, 还是没有就在运行时报错误 crash "unrecognized selector sent to instance"

    class 对象调用和 instance 对象一样, 只不过是去 meta-class 中查找类方法, 最后找不到, 就会从 root-meta-class 找, 如果还是找不到就去 rootclass 找对象方法, 还是没有就在运行时报错误 crash "unrecognized selector sent to class"

    以下是对 isa 指针指向做的代码分析, 断点看下 isa 的地址

    #import <Foundation/Foundation.h>
    #import <objc/runtime.h>
    
    // 对象的 isa 指针指向哪里?
    void about_isa(void);
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
            about_isa();
        }
        return 0;
    }
    
    @interface Test : NSObject
    @end
    @implementation Test
    @end
    
    void about_isa() {
    //    instance 对象的 isa 指针指向 class, 当调用对象方法时, isa 找到 class, 然后找到相应方法进行调用
    //    class 对象的 isa 指针指向 meta-class, 当调用类方法时, isa 找到  meta-class, 然后找到相应方法进行调用
    //    meta-class 对象的 isa 指针指向基类的 meta-class, 基类的指向自己
    //    instance 对象调用流程: instance(subclass) 中的 isa 去 subclass 中找方法, 如果没找到就用 `superclass` 指针找到 subclass 的父类 superclass, 如果还没有就继续递进到 rootclass 中查找, 还是没有就在运行时报错误 crash "unrecognized selector sent to instance"
    //    class 对象调用和 instance 对象一样, 只不过是去 meta-class 中查找类方法, 最后找不到, 就会从 root-meta-class 找, 如果还是找不到就去 rootclass 找**对象方法**, 还是没有就在运行时报错误 crash "unrecognized selector sent to class"
        
        /** lldb 调试一下 test 的 isa 指针地址
         * (lldb) p/x (long)test->isa
         * (long) $1 = 0x001d800100002119
         *
         * 与下面的 testClass 作对比发现 isa 的指针并不是指向类, 其实在 64bits 系统以后 isa 做了调整, 看源码搜索 "ISA_MASK" 就能找到一个宏定义, 将 isa & ISA_MASK 进行位运算才能得到实际的类, 由于我用的是 MacOS 所以对应的 ISA_MASK 为 0x00007ffffffffff8ULL , iOS 为 0x0000000ffffffff8ULL, meta-class 同理可证
         *
         * (lldb) p/x 0x00007ffffffffff8ULL & 0x001d800100002119
         * (unsigned long long) $7 = 0x0000000100002118
         */
        Test *test = Test.new;
        /** lldb 调试一下 testClass 的指针地址
         * (lldb) p/x testClass
         * (Class) $4 = 0x0000000100002118 Test
         *
         * lldb 调试一下, 由于 Class 类型没有暴露 isa 指针, 我需要做一个结构体强转, 这样得到 isa 的地址
         * (lldb) p/x testClass2->isa
         * (Class) $0 = 0x00000001000020f0
         */
        struct object_class {
            Class isa;
        };
        Class testClass = test.class;
        struct object_class *testClass2 = (__bridge struct object_class *)(testClass);
        
        /**
         * (lldb) p/x testMetaClass
         * (Class) $1 = 0x00000001000020f0
         * (lldb) p/x 0x00000001000020f0 & 0x00007ffffffffff8ULL
         * (unsigned long long) $2 = 0x00000001000020f0
         */
        Class testMetaClass = object_getClass(testClass);
        
        NSLog(@"%p - %p - %p - %p", test, testClass, testClass2, testMetaClass);
    }
    
    

    相关文章

      网友评论

          本文标题:对象的 isa 指针指向哪里?

          本文链接:https://www.haomeiwen.com/subject/dbbuphtx.html