isa指针
isa指针的作用就是追溯谁是谁的谁的关系,假设有一个人叫小明,小明是谁的儿子,是谁的孙子。isa指针就是建立一种继承关系。那么isa指针指向该实例对象的类对象。针对于一个对象本身来说,它并不知道如何去应答一个方法,它本身既不包含方法的实现,也不包含有方法的指针。而是间接的通过继承来的isa转到自己的类,才能知道某一个方法。
在Object-C中,任何类的定义都是对象,类与类的对象(实例)并没有本质的区别,也就是类也是一种对象,叫类对象,通过类实例化后的对象,也称为对象,就就是Object-C面向对象语言的精髓,所以,任何对象都有isa指针。
每一个OC对象都有一个隐藏的数据结构,在这个数据结构中的第一个成员变量,它就是isa指针。
在objc.h中能看到类定义:
1 |
|
可以看出: Class是一个objc_class结构类型的指针,id 是一个objc_object结构体类型的指针。
在NSObject.h里面:
1 |
|
再点开 Class 的定义:
1 |
|
isa:是一个Class类型的指针,每个实例对象都有一个isa指针,并且指向对象的类,而Class里也有个isa的指针,指向元类,什么是元类?就是类方法的类,保存了类方法的列表。当某一个类方法被调用时,先会查找本身类方法中的实现方法,如果没有,元类会向他父类查找该方法。元类也是对象,最终指向根元类,根元类isa指向本身。super_class:父类,如果该类已经是最顶层的根类,那么它为NULL。
类通过类的isa指针指向元类,根元类isa指针指向本身。
举例:
假设新建一个Parent,继承与NSObject,里面有成员方法.1
2
3-(void)run;
+(void)sing;
在新建一个类Child,继承于Parent,里面有成员方法.
1 |
|
实例化一个对象Child *xiaoming = [[Child alloc]init];
注意:当我们调用[xiaoming class]的时候,xiaoming会通过它的isa指针去寻找xiaoming 的 class,即 Child。
当我们调用[xiaoming superclass]的时候,xiaoming通过isa找到xiaoming的class即Child类,在通过super_class,找到Parent类。
调用[xiaoming playC],xiaoming通过isa找到Child类,在class的方法列表里面找到playC;
再试着调用[xiaoming run],xiaoming通过isa找到Child类,发现该类里面并没有这个方法,通过该类里面的super_class找到Parent类,在里面的方法列表找到了run;
再是类方法[Child dump],Child通过isa找到Child类,通过该类的isa找到Child的metaclass,在metaclass的方法列表里面找到了+(void)dump;
再试着调用[Child sing],Child通过isa找到Child类,通过该类的isa找到Child的metaclass,发现metaclass里面并没有这个方法,通过metaclass里面的super_class找到Parent的metaclass,在里面的方法列表找到了+(void)sing;
objc_class有两种类型:class与metaclass;class:实例对象的isa指向的结构体;metaclass:class的isa指向的一个结构体;
**`isa` 指针的最大作用 即是 寻找 `谁是谁的谁` 关系。**
总结
微信公众号:嘀咕嘀咕(iOSSharers)
扫二维码关注
