每个Objective-C对象都有一个隐藏的数据结构,这个数据结构是Objective-C对象的第一个成员变量,它就是isa指针。
在NSObject.h里面:
@interface NSObject <NSObject> {
Class isa OBJC_ISA_AVAILABILITY;
}
再点开 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
}
这一些定义对于懂的人自然懂,不会的人根本看不懂。建议看完下面的例子,再点开参考里面的链接仔细看一遍。
现在我们知道的是,对于我们新建的一个类,都会有一个隐藏的属性isa,可以通过它进行一些访问。
我们现在新建一个类ClassParent,继承于NSObject, 里面有成员方法-(void)selectorP,类方法+(void)ClassSelectorP。
再新建一个类ClassChild,继承于ClassParent,里面有成员方法-(void)selectorC, 类方法+(void)ClassSelectorC。
现在我们新建一个实例ClassChild* child = [ClassChlid new];
当我们调用[child class] 的时候,child就会通过isa指针去找到自己的类对象。
当我们调用[child superclass]的时候,child 就会通过super_class 去找到ClassParent的类对象。
在这里,再普及objc_class 的两种类型:
class 实例对象(child)的isa指向的结构体;
metaclass 类对象(Child,注意大写)的isa指向的一个结构体;
接着,调用[child SelectorC],child通过isa找到实例对象的class,在class(注意看上面 struct objc_class 的定义)的方法列表里面找到SelectorC;
再试着调用[child SelectorP],child通过isa找到实例对象的class,发现class里面并没有这个方法,通过class里面的super_class找到ClassParent的class,在里面的方法列表找到了SelectorP;
再是类方法[Child ClassSelectorC],Child(请注意,这个是类对象)通过isa找到类对象的metaclass(实际上也是class,类型是一样的,只是为了区分而叫不一样的名字),在类对象的metaclass的方法列表里面找到了ClassSelectorC;
再试着调用[Child ClassSelectorP],Child通过isa找到类对象的metaclass,发现metaclass里面并没有这个方法,通过metaclass里面的super_class找到ClassParent的metaclass,在里面的方法列表找到了ClassSelectorP;
这是几个例子基本上已经涵盖了大多数调用的情况。
最后总结下:
child 是一个实例对象,可以有多个,isa指向的class也是有多个的;
Child 是一个类对象,只有一个,isa指向的metaclass只有一个。
最后为了理解class和metaclass的作用,大家可以换位思考一下,如果我们作为runtime的设计者,当开发者新建出来一个实例对象child的时候,我们应该存储child的属性和方法,同时又该如何响应其方法调用,最后还要记录与Parent之间的继承关系。
请注意的是,child实际上只是
参考
http://www.cocoachina.com/ios/20141018/9960.html
http://blog.csdn.net/jasonblog/article/details/7246822
http://blog.csdn.net/totogo2010/article/details/8081253