OC 中的类和对象

id和Class的定义

runtime里面,声明了id和Class的类型,简化一下如下:

struct objc_class {

struct objc_class *isa;

};

struct objc_object {

struct objc_class *isa;

};

//  (class object)

typedef struct objc_class *Class; 

// (instance of class)

typedef struct objc_object *id;  

在objc中,id代表了一个对象。根据上面的声明,凡是首地址是*isa的struct指针,都可以被认为是objc中的对象。运行时可以通过isa指针,查找到该对象是属于什么类(Class)。

如果一个类:

@interface Test : NSObject {

int age;

NSString *name;

}

- (void)myAge;

+ (void)myName;

@end

@implementation Test

- (void)myAge {

printf("instance");

}

+ (void)myName {

printf("class");

}

@end

clang -rewrite-objc Test.m

会出现这些内容(只是一部分)

//Class的实际结构

struct _class_t {

struct _class_t *isa;        //isa指针

struct _class_t *superclass; //父类

void *cache;

void *vtable;

struct _class_ro_t *ro;    //Class包含的信息

};

//Class包含的信息

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;                //ivar列表

const unsigned char *weakIvarLayout;

const struct _prop_list_t *properties;            //属性列表

};

//Test(meta-class)

struct _class_t OBJC_METACLASS_$_Test  = {

.isa        = &OBJC_METACLASS_$_NSObject,

.superclass = &OBJC_METACLASS_$_NSObject,

.cache      = (void *)&_objc_empty_cache,

.vtable    = (void *)&_objc_empty_vtable,

.ro        = &_OBJC_METACLASS_RO_$_Test, //包含了类方法等

};

//Test(Class)

struct _class_t OBJC_CLASS_$_Test = {

.isa        = &OBJC_METACLASS_$_Test,  //此处isa指向meta-class

.superclass = &OBJC_CLASS_$_NSObject,

.superclass = (void *)&_objc_empty_cache,

.vtable    = (void *)&_objc_empty_vtable,

.ro        = &_OBJC_CLASS_RO_$_Test,  //包含了实例方法 ivar信息等

};

所有实例的isa都指向了(Class)。

(Class)是一个全局变量,其中记录了类名、成员变量信息、property信息、protocol信息和实例方法列表等。

(Class)的isa指向了全局变量(meta-class),meta-class里只记录了类名、类方法列表等。


Test *test = [[Test alloc] init];

[Test myAge];

向(instance) 发送消息myAge时,运行时会通过isa指针查找到(Class),这里保存着本类中定义的实例方法的指针。

[Test myName];

向(Class)发送消息myName时,运行时会通过isa查找到(meta-class),这里保存着本类中定义的类方法的指针。

继承的话,大概是这样的:

Test *test = [[Test alloc] init];

Class cls = object_getClass(Test); //(Class)

class_getName(cls);              //"Test"

class_isMetaClass(cls);          //NO

Class meta = object_getClass(cls); //(meta-class)

class_getName(meta);              //"Test"

class_isMetaClass(cls);            //YES

Class meta_meta = object_getClass(meta); //NSObject(meta-class)

class_getName(meta_meta);                //"NSObject"

class_isMetaClass(meta_meta);            //YES

}

你可能感兴趣的:(OC 中的类和对象)