Objective-C objc_class 介绍
NSObject
Objective-C 中 NSObject是大多数类的根类。
@interface NSObject <NSObject> { Class isa OBJC_ISA_AVAILABILITY; }
它有一个isa属性,类型是Class.
苹果已经将 ObjC runtime 代码开源了,我们下载下,看看Class究竟是什么http://opensource.apple.com/tarballs/objc4/objc4-493.9.tar.gz
objc_class
我们能够在<objc.h>文件中看到Class的定义
typedef struct objc_class *Class; typedef struct objc_object { Class isa; } *id;
Class 是一个 objc_class 结构类型的指针, id是一个 objc_object 结构类型的指针.
objc_class的定义能够在<runtime.h>里找到
struct objc_class { Class isa; Class super_class; const char *name; long version; long info; long instance_size; struct objc_ivar_list *ivars; struct objc_method_list **methodLists; struct objc_cache *cache; struct objc_protocol_list *protocols; } OBJC2_UNAVAILABLE;
接下来我们来看下每一个属性的意思
isa
是一个 Objective-C Class 类型的指针. 实例对象有个isa的属性,指向Class, 而Class里也有个isa的属性, 指向meteClass. 这里就有个点, 在Objective-C中不论什么的类定义都是对象.
super_class
指向该类的父类, 假设该类已经是最顶层的根类(如 NSObject 或 NSProxy),那么 super_class 就为 NULL.
他们的关系呢,这里有个图http://www.sealiesoftware.com/blog/class%20diagram.pdf
name
我们先看下以下的代码
id objc_getClass(const char *aClassName) { if (!aClassName) return Nil; // NO unconnected, YES class handler return look_up_class(aClassName, NO, YES); } PRIVATE_EXTERN id look_up_class(const char *aClassName, BOOL includeUnconnected, BOOL includeClassHandler) { BOOL includeClassLoader = YES; // class loader cannot be skipped id result = nil; struct old_class query; query.name = aClassName; retry: if (!result && class_hash) { // Check ordinary classes mutex_lock (&classLock); result = (id)NXHashGet(class_hash, &query); mutex_unlock (&classLock); } if (!result && includeUnconnected && unconnected_class_hash) { // Check not-yet-connected classes mutex_lock(&classLock); result = (id)NXHashGet(unconnected_class_hash, &query); mutex_unlock(&classLock); } if (!result && includeClassLoader && _objc_classLoader) { // Try class loader callback if ((*_objc_classLoader)(aClassName)) { // Re-try lookup without class loader includeClassLoader = NO; goto retry; } } if (!result && includeClassHandler && objc_classHandler) { // Try class handler callback if ((*objc_classHandler)(aClassName)) { // Re-try lookup without class handler or class loader includeClassLoader = NO; includeClassHandler = NO; goto retry; } } return result; } struct old_class { struct old_class *isa; struct old_class *super_class; const char *name; long version; long info; long instance_size; struct old_ivar_list *ivars; struct old_method_list **methodLists; Cache cache; struct old_protocol_list *protocols; // CLS_EXT only const uint8_t *ivar_layout; struct old_class_ext *ext; };
objc_getClass从一个字串返回一个类,look_up_class,先创建一个old_class对象,name赋值为这个字串,假设找到了,就返回old_class.看下old_class的结构就能看出name这个属性存的值就是类的名字(事实上name不就是名字嘛)
version
类的版本号信息,默觉得0
info
供执行期使用的一些位标识。
instance_size
该类的实例变量大小
ivars
struct objc_ivar_list { int ivar_count; /* variable length structure */ struct objc_ivar ivar_list[1]; }
成员变量的数组
methodLists
方法定义的数组
struct objc_method_list { struct objc_method_list *obsolete; int method_count; /* variable length structure */ struct objc_method method_list[1]; }
objc_cache
指向近期使用的方法.用于方法调用的优化.
struct objc_cache { unsigned int mask /* total = mask + 1 */; unsigned int occupied; Method buckets[1]; };
protocols
协议的数组
struct objc_protocol_list { struct objc_protocol_list *next; long count; Protocol *list[1]; };