美文网首页
iOS 类的结构初探

iOS 类的结构初探

作者: 北漂少年郎 | 来源:发表于2019-12-22 23:12 被阅读0次

    不寒暄直接切入主题

    问题:

    1 class 底层结构包含什么属性

    2 实例变量存在底层哪里

    3 属性底层如何存放

    4普通方法的存放

    5类方法的存放

    #import

    NS_ASSUME_NONNULL_BEGIN

    @interface LGPerson : NSObject{

        NSString*hobby;

    }

    @property (nonatomiccopy) NSString *nickName;

    - (void)sayHello;

    + (void)sayHappy;

    @end

    首先我们定义一个类,里面有 hobby成员变量,nickName属性, sayHello方法和一个sayHappy类方法

    定义一个        LGPerson*person = [LGPerson personalloc];;万物结对象

    通过        Class pClass =object_getClass(person);拿到当前对象的class

    Class 获取

    Class->objc_class->objc_object 继承关系

    objc_class该类里面是有三个属性加父类一个属性总共是四个属性

     Class_Nonnull isa  OBJC_ISA_AVAILABILITY;

        Class superclass; // 8

        cache_t cache;    // 16      

        class_data_bits_t bits; 

    Class 继承 objc_class objc_calss 内部实现 objc_class 继承objc_object ,objc_object 内部构造

    打印上述所拿到class

    (lldb) x/4gx pClass

    0x1000025f8: 0x001d8001000025d1 0x0000000100b38140

    0x100002608: 0x0000000100f49350 0x0000000400000007

    四个属性对应四个地址

    即 isa ->0x001d8001000025d1    8位

    superclass ->0x0000000100b38140  8位

    cache->0x0000000100f49350  16位

    class_data_bits_t->0x0000000400000007

    第一位 isa跟类的关系验证

    (lldb) po 0x001d8001000025d1 & 0x00007ffffffffff8

    LGPerson

    isa 与上 掩码 就是当前类

    isa 地址打印

    第二位 superclass验证 

    (lldb) po 0x0000000100b38140

    NSObject  

    打印superclass内存地址验证LGPerson 继承与NSObject

    第三位  cache  先不做验证,为啥,因为我也不知道 捂脸.jpg

    第四位 bits重点 探讨

    class_data_bits_t bits;

        class_rw_t*data() { 

     returnbits.data();

        }

    bits 和 data()函数的关系

    可知 data该函数bits可调,进class_rw_t

    class_rw_t 内部实现

    是不是若有所思,对属性,方法,都在这个里面

    我们一步一步进行打印

    (lldb) x/4gx pClass

    0x100002600: 0x001d8001000025d9 0x0000000100b38140

    0x100002610: 0x00000001018205f0 0x0000000300000003

    class 打印

    0x100002600 这个东西为该类地址,也是该类第一个属性isa的地址

    为啥,因为类的第一个属性的地址就是该类的地址

    isa->8位  superclass->8位 cache->16位,可知第一个属性地址评议32位几位第四位属性地址

    bits 数据打印

    直接取 $3里面的数据,

    是不是,不是很惊讶

    其实,还有更惊讶的就是 ro,哪来ro

    又是class_rw_t

    下图 class_ro_t 内部构造

    class_ro_t 内部构造

    我们接着打印ro,一定要把所谓的成员变量,属性,类方法抛出来

    内部数据打印

    ivars->存储成员变量

    为什么我只定义了一个 hobby  _nickName哪来的,

    因为属性在编译时会生成一个_属性名的实例变量

    下面属性

    属性打印

    属性存在于baseProperties 

    对就是这个nickName ,count=1 只有这么一个

    下面方法

    count = 4

    LGPerson sayHello]

    [LGPerson .cxx_destruct]

    [LGPerson nickName]

    [LGPerson setNickName:]

    属性在编译的时候回自动生成setter getter 方法

    问题来了+ (void)sayHappy; 这个类方法呢

    编译完了该类居然没有

    下面我们用一个某人居然说笨的方法来查找一下

    类方法存在于元类

    看见没有元类里面居然有该方法的地址

    说明实例变量编译到了元类里面

    -------------------------------------戛然而止分界线------------------------------------------------------------------

    此次Class结探讨完毕, 由于技术不是很纯属,不足之处还请大神赐教 

    相关文章

      网友评论

          本文标题:iOS 类的结构初探

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