isa指针
- ObjC中有3个层次的对象:实例对象
Instance
、类对象Class
、元类MetaClass
Class
即自定义的类,是实例对象的类对象,类对象又是对应元类的实例对象,它们的关系图如下
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210209121754146.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1MDg3NDI1,size_16,color_FFFFFF,t_70)
isa
指针的作用是可以通过它找到对应的类对象或元类中的方法,例如Instance
对象可以在其类对象中找到它的实例方法,Class
对象可以在元类中找到它的类方法
类方法与实例方法
- 类方法属于类对象,用
+
号修饰,类似于C语言中的static
方法(可以用无需实例对象而用类名访问、只能调用类方法而不能调用实例方法、不能访问成员变量),类方法存在类对象的元类中 - 实例方法属于实例对象,用
-
号修饰,访问它必须用实例对象,实例方法存在实例对象的类对象中
消息传递机制
- OC中,方法调用不再理解为对象调用其方法,而是对象接收消息。对象为
receiver
,调用的方法及参数就是message
,格式为[receiver message]
,编译器将其转为C语言函数调用,核心函数objc_msgSend
定义如下:
void objc_msgSend(id self, SEL cmd,…)
- 参数
self
代表消息接受者,SEL
代表方法名,每个类中的methodLists
类似于一张表格,IMP
指针指向方法的实现,SEL
就是查表所用的key objc_msgSend
函数的基本流程如下:
① 通过isa
指针在receiver
所属的类中搜寻方法列表,若能找到就跳转到实现代码
② 若找不到,会通过superclass
指针沿着类的继承体系继续向上查找,若能找到就跳转
③ 若到了根类还是无法找到对应的方法,触发消息转发机制。
SEL与IMP
SEL
- ObjC在编译时会根据每个方法的名字、参数列表生成一个唯一的整型标识即
SEL
- 正因其唯一性,在ObjC的同一个类中不能存在两个同名的方法(不支持重载),即使参数类型不同也不行
IMP
- 也是个函数指针,指向方法实现的首地址,可以理解为方法的具体实现
objc_method
结构体包含了一个SEL
和一个IMP
,相当于做了一个映射,因此通过SEL
可以找到对应的IMP