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;属性列表
};