iOS类本质探究(一)

咱们先来解释一下苹果官方给开发者提供的这张图bash

20190621191847.jpg

例如咱们建立个本身的类 LWPerson *person = [[LWPerson alloc] init];每一个类都有本身的isa,它指向对应的了[LWPerson Class],[LWPerson Class]也有本身的isa,它则指向对应的元类meta;这里解释一下两个问题spa

Q : Instance(类对象),class(类),meta(即meta-class元类) 里面各存着这么设计

A : Instance 存着一个isa指向class,还存着本身的成员变量;class里存有isasuperclass,属性、对象方法、协议、成员变量等;meta里存在isa,superclass,类方法等;如图(图片引用自李明杰老师)3d

79a2f72d-1be5-45cc-b41e-c1392149501f.jpg
Q : 为何 isa要这样指来指去,这样有什么好处

A : 例如这段代码指针

LWPerson *person = [[LWPerson alloc] init]; 
 person.age = 20;
 persom.height = 180;
 [person  sing];
 [person dance];
 [person rap];
复制代码

其中ageheight都是每一个LWPerson私有的,每建立一个LWPerson均可能不同,可是singdancerap方法是每个LWPerson共有。因此当建立LWPerson对象后,只需isa和成员变量,全部的方法都放在LWPerson的类里,对象经过isa找到对应类的的方法,这样能够大大的节省LWPerson对象所占用的内存。这里LWPerson类的isa指向LWPerson的元类,类方法就存在元类里,也很好的解释了通常状况下 类方法为何不能使自己的成员变量,由于存在类对象上;code

接回以前的继续说:每一个类都存有一个superclass指针,这很好理解,子类若是找不到对应的方法,便会顺着superclass指针找到对应的父类。meta的也同样自己没有的类方法也会去寻找父类的类方法,这样一直一级一级往上传,一直传到Root Class, Root Class的元类比较特殊,苹果设计它的isa指向本身,superclass指向Root Class,若是Root Class也找不到方法,就会报一个咱们很熟悉的错误 unrecognized selector sent to instance 0x600001a3a5b0cdn

可能上面说的比较多比较乱,咱们能够举个栗子再捋一次 首先,咱们建立个类LWPerson继承于NSObject对象

LWPerson *person = [[LWPerson alloc] init];
复制代码

在建立LWPerson的时候,咱们用的[LWPerson alloc]本质就是 LWPerson类经过isameta里找类方法,可是找不到!就再经过metasuperclass找到它的父metaNSObjectmeta, NSObject的类方咱们很容易就能够找到allocinit也是同理,咱们在[LWPerson alloc]后,它实际上返回的是一个LWPerson的对象,它自己也没有init对象方法,因此找它的父类NSObject 的对象方法init blog

20190621192701.jpg

咱们也能够在LWPerson.h中声明一个-(void)sing方法,但不写实现,这样person对象就会去LWPerson的类里找sing方法,但没实现sing方法,就会顺着superclassNSObject到对象方法,但NSObject也没有sing方法,因此继续往上找到了Root Class,但Root Class也没有sing方法,因此指向nil,系统报错 unrecognized selector sent to instance继承

20190621192643.jpg
这就是方法系统调用的过程,固然还有很多更底层更细致的流程,篇幅缘由就下次再细聊了
相关文章
相关标签/搜索