NSObject
C语言中,在编译期,函数的调用就会决定调用哪个函数;而OC的函数,属于动态调动过程,在编译期并不能决定真正调用哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数来调用
typedef struct objc_class *Class;
@interface NSObject <NSObject> {
Class isa OBJC_ISA_AVAILABILITY;
}
Objc2.0之前,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;
在一个类中,有超类指针、类名、版本等信息,ivars是objc_ivar_list成员列表的指针,methodLists是指向objc_method_list方法列表指针的指针。
*methodLists是指向方法列表的指针,所以可以通过动态修改*methodLists的值来为类添加方法
Objc2.0之后,objc_class源码:
typedef struct objc_class *Class;
typedef struct objc_object *id;
@interface Object {
Class isa;
}
@interface NSObject <NSObject> {
Class isa OBJC_ISA_AVAILABILITY;
}
struct objc_object {
private:
isa_t isa;
}
struct objc_class : objc_object {
// Class ISA;
Class superclass;
cache_t cache; // formerly cache pointer and vtable 以前缓存的指针和函数表
class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags
}
union isa_t
{
isa_t() { }
isa_t(uintptr_t value) : bits(value) { }
Class cls;
uintptr_t bits;
}
Objective-C对象都是C语言结构体实现的,所有的对象都包含一个isa_t类型的结构体
objc_object被源码typedef成了id类型,这也就是我们平时遇到的id类型,这个结构体中就只包含了一个isa_t类型的结构体
objc_class继承于objc_object,所以在objc_class中会包含一个isa_t类型的结构体isa,而且可以看出Objective-C中类也是一个对象。在objc_class中,除了isa之外,还包含着父类的指针、方法缓存、这个类的实例方法链表
Object类和NSObject类里边都包含了一个objc_class类型的isa
当一个对象的实例方法被调用的时候,会通过isa找到相应的类,然后在该类的class_data_bits_t中去查找方法。class_data_bits_t指向了类对象的数据区域,在该数据区域内查找相应方法的对应实现
对象的实例方法调用时,通过对象的isa在类中获取方法的实现
类对象的类方法调用时,通过类的isa在元类中获取方法的实现
Root class(class)其实就是NSObject,NSObject是没有超类的,所以Root class(class)的superclass指向nil
每个Class都有一个isa指针指向唯一的Meta class,它存储着一个类的所有类方法
Root class(meta)的superclass指向Root class(class),也就是NSObject,形成一个回路
每个Meta class的isa指针都指向Root class(meta)