欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OC类的定义

程序员文章站 2024-01-14 21:12:34
...

本文通过阅读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_$_TestClassOBJC_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,
};