本帖最后由 xiniuniu 于 2014-9-13 15:43 编辑
- typedef struct objc_class *Class;
- typedef struct objc_object {
- Class isa;
- } *id;
- @interface NSObject <NSObject> {
- Class isa;
- }
- // (runtime.h)
- struct objc_class {
- Class isa;
- #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;
复制代码
Class是typedef定义的指向 objc_class结构体指针类型的别名, 而id则是typedef定义的指向objc_object 结构体指针类型别名,在这个结构体中只有一个指向objc_class结构体的指针isa;
NSObject类中也只有一个Class类型成员变量isa
可以说他们三个的类型是一样的。作用区别也是不大的
objc_class结构体存放类的“元数据”(metadata),例如类的实例实现了几个方法,具备多少个实例变量等信息。此结构体的首个变量也是isa指针,这说明Class本身亦为Objectiove-C对象。结构体里还有个变量叫super_class,它定义了本类的超类。类对象所属的类型(也就是isa所指向的类型)是另外一个类,叫做“元类”(metaclass),用来表述类对象本身所具备的元数据。“类方法”就定义于此处,因为这些方法可以理解成类对象的实例方法。第个类仅有一个“类对象”,而每个“类对象”仅有一个与这相关的“元类”。
所设有个名为SomeClass的子类从NSObject中继承而来,则继承体系如图:
图中也画出了两个对应“元类”之间的继承关系
super_class指针确立了继承关系,而isa指针描述了实例所属的类。通过这张布局关系图即可执行“类型信息查询”。我们可以查出对象是否能响应某个选择子,是否遵从某项协议,并能看到对象位于“类继承体系”的哪一部分。
以上图片和文字摘自《Effective Objective-C 2.0 编写高质量iOS与OS X代码的52个有效方法》
这也说明了id为什么是万能指针。只要给他任何一个对象地址。他就可以通过这个继承关系找到可以调用的方法等信息。
|