OC类的定义
本文通过阅读runtime代码来分析NSObject。我们都知道NSObject是oc继承的跟类,提供一些通用的方法。从定义上看到NSObject满足NSObject协议,NSObject协议定义一些基础方法。
把NSObject.h用clang -rewrite-objc转成c++代码会发现NSObject的定义
#ifndef _REWRITER_typedef_NSObject
#define _REWRITER_typedef_NSObject
typedef struct objc_object NSObject;
typedef struct {} _objc_exc_NSObject;
#endif
struct NSObject_IMPL {
Class isa;
};
发现NSObject是struct的别名,也就是说所有的类都是objc_object类型的结构体。NSObject的属性都存放在NSObject_IMPL这个结构体中。在编码中我们知道所有的类都可以赋值给id类型,这是为什么呢?在objc-private.h中可以找到id的定义:
typedef struct objc_class *Class;
typedef struct objc_object *id;
struct objc_object {
...
}
struct objc_class : objc_object {
...
}
Class是objc_class类型指针,id是objc_object类型的指针,所有的类也都是objc_object。
上面NSObject定义后面跟着一个NSObject_IMPL结构体,他存放着NSObject的变量。加一段测试代码。
@interface TestClass : NSObject
@property (nonatomic,assign) int i;
- (int)plus:(int)j;
@end
@implementation TestClass
- (int)plus:(int)j {
return self.i+j;
}
转成c++代码后,声明的部分:
#ifndef _REWRITER_typedef_TestClass
#define _REWRITER_typedef_TestClass
typedef struct objc_object TestClass;
typedef struct {} _objc_exc_TestClass;
#endif
extern "C" unsigned long OBJC_IVAR_$_TestClass$_i;
struct TestClass_IMPL {
struct NSObject_IMPL NSObject_IVARS;
int _i;
};
TestClass同样被定义为objc_object的别名,这里并没有体现和NSObject的关系。但是在存放变量的TestClass_IMPL内体现了对NSOBject的继承关系,NSObject_IMPL作为了TestClass_IMPL的第一个数据。
static int _I_TestClass_i(TestClass * self, SEL _cmd) { return (*(int *)((char *)self + OBJC_IVAR_$_TestClass$_i)); }
static void _I_TestClass_setI_(TestClass * self, SEL _cmd, int i) { (*(int *)((char *)self + OBJC_IVAR_$_TestClass$_i)) = i; }
实现部分,默认生成了get和set两个静态方法,参数是对象和方法名。知道了变量是如何继承的,那类名是如何关联上的呢?在runtime初始化时会调用OBJC_CLASS_SETUP函数,进行类对象、元类对象中 isa、superclass 变量的设置。
static struct _class_ro_t _OBJC_METACLASS_RO_$_TestClass __attribute__ ((used, section ("__DATA,__objc_const"))) = {
1, sizeof(struct _class_t), sizeof(struct _class_t),
(unsigned int)0,
0,
"TestClass",
0,
0,
0,
0,
0,
};
static struct _class_ro_t _OBJC_CLASS_RO_$_TestClass __attribute__ ((used, section ("__DATA,__objc_const"))) = {
0, __OFFSETOFIVAR__(struct TestClass, _i), sizeof(struct TestClass_IMPL),
(unsigned int)0,
0,
"TestClass",
(const struct _method_list_t *)&_OBJC_$_INSTANCE_METHODS_TestClass,
0,
(const struct _ivar_list_t *)&_OBJC_$_INSTANCE_VARIABLES_TestClass,
0,
(const struct _prop_list_t *)&_OBJC_$_PROP_LIST_TestClass,
};
extern "C" __declspec(dllimport) struct _class_t OBJC_METACLASS_$_NSObject;
extern "C" __declspec(dllexport) struct _class_t OBJC_METACLASS_$_TestClass __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_$_TestClass,
};
extern "C" __declspec(dllimport) struct _class_t OBJC_CLASS_$_NSObject;
extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_TestClass __attribute__ ((used, section ("__DATA,__objc_data"))) = {
0, // &OBJC_METACLASS_$_TestClass,
0, // &OBJC_CLASS_$_NSObject,
0, // (void *)&_objc_empty_cache,
0, // unused, was (void *)&_objc_empty_vtable,
&_OBJC_CLASS_RO_$_TestClass,
};
static void OBJC_CLASS_SETUP_$_TestClass(void ) {
OBJC_METACLASS_$_TestClass.isa = &OBJC_METACLASS_$_NSObject;
OBJC_METACLASS_$_TestClass.superclass = &OBJC_METACLASS_$_NSObject;
OBJC_METACLASS_$_TestClass.cache = &_objc_empty_cache;
OBJC_CLASS_$_TestClass.isa = &OBJC_METACLASS_$_TestClass;
OBJC_CLASS_$_TestClass.superclass = &OBJC_CLASS_$_NSObject;
OBJC_CLASS_$_TestClass.cache = &_objc_empty_cache;
}
#pragma section(".objc_inithooks$B", long, read, write)
__declspec(allocate(".objc_inithooks$B")) static void *OBJC_CLASS_SETUP[] = {
(void *)&OBJC_CLASS_SETUP_$_TestClass,
};
OBJC_CLASS_$_TestClass和OBJC_METACLASS_$_TestClass都是_class_t类型,其中的class_ro_t中包含了类名(name)、method_list_t(方法列表)、protocol_list_t(协议列表)、ivar_list_t(实例变量列表)、property_list_t(属性列表)等信息。
struct _class_t {
struct _class_t *isa;
struct _class_t *superclass;
void *cache;
void *vtable;
struct _class_ro_t *ro;
};
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;
};
类会生成一个名为OBJC_CLASS_$_TestClass的_class_t类型结构体来存储它的一些信息。所以类都会生成对应的结构体变量,它的isa指向它的元类结构体变量(_class_t同类型),supperclass指向它继承类的结构体变量。实例方法定义在类中,类方法定义在元类中。元类的isa和supperclass指向继承类的元类结构体变量。
最后OBJC_CLASS_$_TestClass还会存放到L_OBJC_LABEL_CLASS_$数组中。
static struct _class_t *L_OBJC_LABEL_CLASS_$ [1] __attribute__((used, section ("__DATA, __objc_classlist,regular,no_dead_strip")))= {
&OBJC_CLASS_$_TestClass,
};
上一篇: ADO.NET之小白教程(增删改)
下一篇: cpp调用c头文件引用方法