美文网首页
runtime-objc 类结构

runtime-objc 类结构

作者: _东阁堂主_ | 来源:发表于2021-03-23 21:51 被阅读0次

    运行时特性
    Objectiv-C = C + Preprocessor(预处理器) + runtime
    编译器Clang把OC代码编译成C++代码
    运行时系统Runtime,执行编译后的代码

    核心功能
    c结构体->封装 -> OC类
    执行OC方法 ->消息机制 ->执行C函数
    编译OC文件
    clang -rewrite-objc Person.m
    runtime 源码
    apple source:
    https://opensource.apple.com/source/bojc4/
    强制转换(
    ((void()(id,SEL,int))(void)objc_mesgSend)
    //通过这个设置可以进行objc_mesgSend直接调用 不用转换
    Build Settings -> Enable Strict Checking of objc_msgSend Calls -> NO

    类的结构

     struct objc_class {
        Class _Nonnull isa  OBJC_ISA_AVAILABILITY; //类中isa
    
    #if !__OBJC2__
        Class _Nullable super_class        //父类                       OBJC2_UNAVAILABLE;
        const char * _Nonnull name        //类名                OBJC2_UNAVAILABLE;
        long version                                             OBJC2_UNAVAILABLE;
        long info                                                OBJC2_UNAVAILABLE;
        long instance_size                                       OBJC2_UNAVAILABLE;
        struct objc_ivar_list * _Nullable ivars                OBJC2_UNAVAILABLE;  //属性
        struct objc_method_list * _Nullable * _Nullable methodList    OBJC2_UNAVAILABLE; //方法
        struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE; //方法
        struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE; //协议列表
    #endif
    
    } OBJC2_UNAVAILABLE;
    /* Use `Class` instead of `struct objc_class *` */
    

    类中的rw

    struct class_rw_ext_t {
        const class_ro_t *ro;
        method_array_t methods; //方法列表
        property_array_t properties; //属性类别
        protocol_array_t protocols; //协议列表
        char *demangledName;
        uint32_t version;
    };
    

    类中的ro

    struct class_ro_t {
        uint32_t flags;
        uint32_t instanceStart;
        uint32_t instanceSize;
    #ifdef __LP64__
        uint32_t reserved;
    #endif
    
        const uint8_t * ivarLayout;
        
        const char * name;
        method_list_t * baseMethodList;
        protocol_list_t * baseProtocols;
        const ivar_list_t * ivars;
    
        const uint8_t * weakIvarLayout;
        property_list_t *baseProperties;
    

    方法结构体

    struct method_t {
        SEL name; //方法名
        const char *types;//方法类型
        MethodListIMP imp;//方法地址
    
        struct SortBySELAddress :
            public std::binary_function<const method_t&,
                                        const method_t&, bool>
        {
            bool operator() (const method_t& lhs,
                             const method_t& rhs)
            { return lhs.name < rhs.name; }
        };
    };
    

    协议列表

    struct protocol_list_t {
        // count is pointer-sized by accident.
        uintptr_t count;
        protocol_ref_t list[0]; // variable-size
    
        size_t byteSize() const {
            return sizeof(*this) + count*sizeof(list[0]);
        }
    
    };
    struct protocol_t : objc_object {
        const char *mangledName; //协议名
        struct protocol_list_t *protocols; //协议列表
        method_list_t *instanceMethods;//实例方法
        method_list_t *classMethods; //类方法
        method_list_t *optionalInstanceMethods;//可选实例方法
        method_list_t *optionalClassMethods;//可选类方法
        property_list_t *instanceProperties;//实例属性
        uint32_t size;   // sizeof(protocol_t)
        uint32_t flags;
        // Fields below this point are not always present on disk.
        const char **_extendedMethodTypes;
        const char *_demangledName;
        property_list_t *_classProperties;
    
        const char *demangledName();
    
        const char *nameForLogging() {
            return demangledName();
        }
    }
    

    属性列表

    class property_array_t : 
        public list_array_tt<property_t, property_list_t> 
    {
        typedef list_array_tt<property_t, property_list_t> Super;
    
     public:
        property_array_t() : Super() { }
        property_array_t(property_list_t *l) : Super(l) { }
    
        property_array_t duplicate() {
            return Super::duplicate<property_array_t>();
        }
    };
    
    struct property_t {
        const char *name; //属性名
        const char *attributes;//属性内容:strong weak 编码等
    };
    

    类的结构

    image

    验证上面这个经典的类的结构模型
    //创建一个person类并在方法中做出下列打印

        NSLog(@"Person 实例对象的地址:%@",self);//实例对象
        Class myclass = objc_getClass("CFPerson");//类对象
        NSLog(@"Person 的类地址:%p",myclass);
        Class metaClass = objc_getMetaClass("CFPerson");//元类对象的地址
        NSLog(@"Person 的元类地址:%p",metaClass);
        Class superClass = class_getSuperclass(myclass);//父类对象
        NSLog(@"Person 父类的地址:%@:%p",superClass,superClass);
        NSObject *obj = [NSObject new];//NSObject 实例对象
        NSLog(@"NSObject实例对象地址:%p",obj);
        Class objClass = objc_getClass("NSObject"); //类对象
        NSLog(@"NSObject 的类地址:%p",objClass);
        Class objMetaClass = objc_getMetaClass("NSObject");
        NSLog(@"NSObject 的元类地址:%p",objMetaClass); //元类对象的地址
        //父类对象
        Class objSuperClass = class_getSuperclass(objClass);
        NSLog(@"NSObject 父类的地址:%@:%p",objSuperClass,objSuperClass);
        //元类对象的父类的地址 应该是NSObject 的地址
        Class objMetaSuperClass = class_getSuperclass(objMetaClass);
        NSLog(@"objMetaSuperClass 的元类地址:%p",objMetaSuperClass);
        NSLog(@"---------");
        NSLog(@"@Person实例的isa:%p",object_getClass(self));
        NSLog(@"Person类的isa:%p",object_getClass(myclass));
        NSLog(@"Person元类的isa:%p",object_getClass(metaClass));
        
        NSLog(@"@NSObject实例的isa:%p",object_getClass(obj));
        NSLog(@"NSObject类的isa:%p",object_getClass(objClass));
        NSLog(@"NSObject元类的isa:%p",object_getClass(objMetaClass));
    

    看先打印结果:

    Person 实例对象的地址:<CFPerson: 0x1032948d0>
    Person 的类地址:0x100008138
    Person 的元类地址:0x100008110
    Person 父类的地址:NSObject:0x7fff993fb118
    NSObject实例对象地址:0x100410520
    NSObject 的类地址:0x7fff993fb118
    NSObject 的元类地址:0x7fff993fb0f0
    NSObject 父类的地址:(null):0x0
    objMetaSuperClass 的元类地址:0x7fff993fb118
     ---------
    Person实例的isa:0x100008138
    Person类的isa:0x100008110
    Person元类的isa:0x7fff993fb0f0
    NSObject实例的isa:0x7fff993fb118
    NSObject类的isa:0x7fff993fb0f0
    NSObject元类的isa:0x7fff993fb0f0
    

    开始分析:
    Person 的父类是NSObject ,因为Person继承自NSObject,

    Person 父类的地址:NSObject:0x7fff993fb118 和
    NSObject 的类地址:0x7fff993fb118 地址是一样的
    NSObject 父类的地址:(null):0x0 NSObject 父类是nil
    Person的isa指向其元类 其元类的isa 指向NSObject的元类
    NSObject的元类的isa 指向的是自己

    WeChate55585c6ef593efe89bb041b256a26ed.png

    相关文章

      网友评论

          本文标题:runtime-objc 类结构

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