转载请注明出处http://blog.csdn.net/u014205968/article/details/64921601
面向对象中每一个对象都必须依赖一个类来创建,因此对象的isa
指针就指向对象所属的类根据这个类模板能够创建出实例变量、实例方法等。
比如有如下代码
NSString* str = @"Hello World";
通过上文我们知道这个str
对象本质就是一个objc_object
结构体,而这个结构体的成员变量isa
指针则表明了str is a NSString
,因此这个isa
就指向了NSString
类,这个NSString
类其实是类对象,不明白就继续往下看吧。
class object/metaclass
继续查看结构体objc_class
的定义
struct objc_class { Class isa OBJC_ISA_AVAILABILITY; #if !__OBJC2__ Class super_class OBJC2_UNAVAILABLE; const char *name OBJC2_UNAVAILABLE; long version OBJC2_UNAVAILABLE; long info OBJC2_UNAVAILABLE; long instance_size OBJC2_UNAVAILABLE; struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; struct objc_method_list **methodLists OBJC2_UNAVAILABLE; struct objc_cache *cache OBJC2_UNAVAILABLE; struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; #endif } OBJC2_UNAVAILABLE; /* Use `Class` instead of `struct objc_class *` */
struct objc_classs
结构体里存放的数据称为元数据(metadata)
,通过成员变量的名称我们可以猜测里面存放有指向父类的指针、类的名字、版本、实例大小、实例变量列表、方法列表、缓存、遵守的协议列表等,这些信息就足够创建一个实例了,该结构体的第一个成员变量也是isa
指针,这就说明了Class
本身其实也是一个对象,我们称之为类对象
,类对象
在编译期产生用于创建实例对象,是单例,因此前文中的栗子其实应该表达为str的isa指针指向了NSString类对象
那么这个结构体的isa
指针又指向什么呢?
类对象
中的元数据
存储的都是如何创建一个实例的相关信息,那么类对象
和类方法
应该从哪里创建呢?就是从isa
指针指向的结构体创建,类对象
的isa
指针指向的我们称之为元类(metaclass)
,元类
中保存了创建类对象
以及类方法
所需的所有信息,因此整个结构应该如下图所示: