ivar和property

2020-11-06  本文已影响0人  康小曹

Student代码:


@interface XKStudent : XKPerson {
    @public int _testMember;
}

@property (copy, nonatomic) NSString *school;

@property (copy, nonatomic) NSString *grade;

@end

先看 转译之后的 _class_ro_t 源码:

static struct _class_ro_t _OBJC_CLASS_RO_$_XKStudent = {
    0,
    __OFFSETOFIVAR__(struct XKStudent, _testMember),
    sizeof(struct XKStudent_IMPL),
    0, 
    "XKStudent",
    (const struct _method_list_t *)&_OBJC_$_INSTANCE_METHODS_XKStudent,
    0, 
    (const struct _ivar_list_t *)&_OBJC_$_INSTANCE_VARIABLES_XKStudent,
    0, 
    (const struct _prop_list_t *)&_OBJC_$_PROP_LIST_XKStudent,
};

之前已经整理过,_class_ro_t 会被 class_t 对象持有,class_t 关键在于 isa 和 superclass 两个指针和 cache。而 _class_ro_t 则主要管理 成员变量、方法、协议、属性。isa、superclass 等的设置会通过 class_setup 相关方法设置,具体源码就不贴出来了。

看的出来:

  1. _ivar_list_t 为:OBJC$_INSTANCE_VARIABLES_XKStudent,表示实例对象的成员变量;
  2. _prop_list_t 为:OBJC$_PROP_LIST_XKStudent,表示属性列表;

这就是 ivar 列表和属性列表;
_INSTANCE_VARIABLES_XKStudent:

static struct /*_ivar_list_t*/ {
    unsigned int entsize;  // sizeof(struct _prop_t)
    unsigned int count;
    struct _ivar_t ivar_list[3];
} _OBJC_$_INSTANCE_VARIABLES_XKStudent  = {
    sizeof(_ivar_t),
    3,
    {{&OBJC_IVAR_$_XKStudent$_testMember, "_testMember", "i", 2, 4},
     {&OBJC_IVAR_$_XKStudent$_school, "_school", "@\"NSString\"", 3, 8},
     {&OBJC_IVAR_$_XKStudent$_grade, "_grade", "@\"NSString\"", 3, 8}}
};

_PROP_LIST_XKStudent:

static struct /*_prop_list_t*/ {
    unsigned int entsize;  // sizeof(struct _prop_t)
    unsigned int count_of_properties;
    struct _prop_t prop_list[2];
} _OBJC_$_PROP_LIST_XKStudent __attribute__ ((used, section ("__DATA,__objc_const"))) = {
    sizeof(_prop_t),
    2,
    {{"school","T@\"NSString\",C,N,V_school"},
    {"grade","T@\"NSString\",C,N,V_grade"}}
};

总结:

  1. 属性是 ivar 的子集;
  2. 属性是通过编译器特性生成的,不仅添加到了成员变量,还添加了 setter 和setter 和 getter 以支持点语法;
  3. _xxx 则是直接追加到结构体中,不能使用点语法的;
上一篇 下一篇

猜你喜欢

热点阅读