iOS 中类的本质

2019-12-17  本文已影响0人  嗨哒哥
@interface Person : NSObject
@property (copy, nonatomic) NSString *name;
- (void)addtarget;
- (instancetype)initWithName:(NSString *)name;
+ (instancetype)getInstance;
@end


@implementation Person
- (void)addtarget {
    
}
- (instancetype)initWithName:(NSString *)name {
return self;
}
+ (instancetype)getInstance {
return nil;
}
@end


int main(int argc, const char * argv[]) {
@autoreleasepool {
    // insert code here...
    NSLog(@"Hello, World!");
}
return 0;
}

通过对上述代码使用clang -rewrite-objc解析后,可以得到如下信息:

声明成员变量IVAR:
extern "C" unsigned long int OBJC_IVAR_$_Person$_name __attribute__ ((used, section ("__DATA,__objc_ivar"))) = __OFFSETOFIVAR__(struct Person, _name);
extern "C" unsigned long int OBJC_IVAR_$_Person$_age __attribute__ ((used, section ("__DATA,__objc_ivar"))) = __OFFSETOFIVAR__(struct Person, _age);

成员变量列表,包含大小、数量、
static struct /*_ivar_list_t*/ {
    unsigned int entsize;  // sizeof(struct _prop_t)空间大小
    unsigned int count;数量
    struct _ivar_t ivar_list[2]; _ivar_t结构体指针
} _OBJC_$_INSTANCE_VARIABLES_Person __attribute__ ((used, section ("__DATA,__objc_const"))) = {
    sizeof(_ivar_t),
    2,
    {{(unsigned long int *)&OBJC_IVAR_$_Person$_name, "_name", "@\"NSString\"", 3, 8},
     {(unsigned long int *)&OBJC_IVAR_$_Person$_age, "_age", "@\"NSString\"", 3, 8}}
};
实例方法列表:包含占用空间大小、方法数量
static struct /*_method_list_t*/ {
    unsigned int entsize;  // sizeof(struct _objc_method)申请空间大小
    unsigned int method_count;方法数量
    struct _objc_method method_list[6]; _objc_method结构体指针,存放方法具体描述
} _OBJC_$_INSTANCE_METHODS_Person __attribute__ ((used, section ("__DATA,__objc_const"))) = {
    sizeof(_objc_method),
    6,
    {{(struct objc_selector *)"addtarget", "v16@0:8", (void *)_I_Person_addtarget},
    {(struct objc_selector *)"initWithName:", "@24@0:8@16", (void *)_I_Person_initWithName_},
    {(struct objc_selector *)"name", "@16@0:8", (void *)_I_Person_name},
    {(struct objc_selector *)"setName:", "v24@0:8@16", (void *)_I_Person_setName_},
    {(struct objc_selector *)"age", "@16@0:8", (void *)_I_Person_age},
    {(struct objc_selector *)"setAge:", "v24@0:8@16", (void *)_I_Person_setAge_}}
};

类方法列表:包含占用空间大小、类方法数量
static struct /*_method_list_t*/ {
    unsigned int entsize;  // sizeof(struct _objc_method)占用空间大小
    unsigned int method_count;类方法大小
    struct _objc_method method_list[1];存放类方法描述信息
} _OBJC_$_CLASS_METHODS_Person __attribute__ ((used, section ("__DATA,__objc_const"))) = {
    sizeof(_objc_method),
    1,
    {{(struct objc_selector *)"getInstance", "@16@0:8", (void *)_C_Person_getInstance}}
};

属性列表:注意与成员变量作区分 
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_Person __attribute__ ((used, section ("__DATA,__objc_const"))) = {
    sizeof(_prop_t),
    2,
    {{"name","T@\"NSString\",C,N,V_name"},
    {"age","T@\"NSString\",C,N,V_age"}}
};
声明Person类的_class_ro_t,并且指定类方法列表和调用类
static struct _class_ro_t _OBJC_METACLASS_RO_$_Person __attribute__ ((used, section ("__DATA,__objc_const"))) = {
    1, sizeof(struct _class_t), sizeof(struct _class_t), 
    (unsigned int)0, 
    0, 
    "Person",
    (const struct _method_list_t *)&_OBJC_$_CLASS_METHODS_Person,
    0, 
    0, 
    0, 
    0, 
};
声明Person类的_class_ro_t,并指定实例方法,成员变量,属性的调用声明
static struct _class_ro_t _OBJC_CLASS_RO_$_Person __attribute__ ((used, section ("__DATA,__objc_const"))) = {
    0, __OFFSETOFIVAR__(struct Person, _name), sizeof(struct Person_IMPL), 
    (unsigned int)0, 
    0, 
    "Person",
    (const struct _method_list_t *)&_OBJC_$_INSTANCE_METHODS_Person,
    0, 
    (const struct _ivar_list_t *)&_OBJC_$_INSTANCE_VARIABLES_Person,
    0, 
    (const struct _prop_list_t *)&_OBJC_$_PROP_LIST_Person,
};

extern "C" __declspec(dllimport) struct _class_t OBJC_METACLASS_$_NSObject;

extern "C" __declspec(dllexport) struct _class_t OBJC_METACLASS_$_Person __attribute__ ((used, section ("__DATA,__objc_data"))) = {
    0, // &OBJC_METACLASS_$_NSObject,
    0, // &OBJC_METACLASS_$_NSObject,
    0, // (void *)&_objc_empty_cache,
    0, // unused, was (void *)&_objc_empty_vtable,
    &_OBJC_METACLASS_RO_$_Person,
};

extern "C" __declspec(dllimport) struct _class_t OBJC_CLASS_$_NSObject;

extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_Person __attribute__ ((used, section ("__DATA,__objc_data"))) = {
    0, // &OBJC_METACLASS_$_Person,
    0, // &OBJC_CLASS_$_NSObject,
    0, // (void *)&_objc_empty_cache,
    0, // unused, was (void *)&_objc_empty_vtable,
    &_OBJC_CLASS_RO_$_Person,
};
static void OBJC_CLASS_SETUP_$_Person(void ) {
    OBJC_METACLASS_$_Person.isa = &OBJC_METACLASS_$_NSObject;
    OBJC_METACLASS_$_Person.superclass = &OBJC_METACLASS_$_NSObject;
    OBJC_METACLASS_$_Person.cache = &_objc_empty_cache;
    OBJC_CLASS_$_Person.isa = &OBJC_METACLASS_$_Person;
    OBJC_CLASS_$_Person.superclass = &OBJC_CLASS_$_NSObject;
    OBJC_CLASS_$_Person.cache = &_objc_empty_cache;
}

_ivar_t结构体指针,里面存放实例变量的偏移、名称、类型、对齐方式、空间大小

struct _ivar_t {
    unsigned long int *offset;  // pointer to ivar offset location
    const char *name;
    const char *type;
    unsigned int alignment;
    unsigned int  size;
};

_objc_method结构体指针,用来描述实例方法

struct _objc_method {
    struct objc_selector * _cmd;方法的选择结构体
    const char *method_type;方法类型
    void  *_imp;方法的imp指针
};

属性结构体指针:

struct _prop_t {
    const char *name;名称
    const char *attributes;描述信息
};

_class_ro_t的结构体声明:

struct _class_ro_t {
unsigned int flags;标志位
unsigned int instanceStart;起始位置
unsigned int instanceSize;大小
unsigned int reserved;转换
const unsigned char *ivarLayout;实例变量布局
const char *name;名称
const struct _method_list_t *baseMethods;方法列表
const struct _objc_protocol_list *baseProtocols;协议列表
const struct _ivar_list_t *ivars;实例变量列表
const unsigned char *weakIvarLayout;弱引用实例变量布局
const struct _prop_list_t *properties;属性列表
};

_class_t结构体指针:

struct _class_t {
    struct _class_t *isa;指向自己的指针
    struct _class_t *superclass;指向父类的指针
    void *cache;缓存,缓存方法
    void *vtable;
    struct _class_ro_t *ro;引用_class_ro_t结构体,用于获取方法,变量
};

_category_t分类结构体指针:

struct _category_t {
    const char *name;名称
    struct _class_t *cls;指向本类
    const struct _method_list_t *instance_methods;实例方法列表
    const struct _method_list_t *class_methods;类方法列表
    const struct _protocol_list_t *protocols;协议列表
    const struct _prop_list_t *properties;属性列表
};
上一篇下一篇

猜你喜欢

热点阅读