调用一个方法时,编译器通过插入一些代码,将之转换成对方法具体实现IMP的调用
编译器会将消息转换为对消息函数objc_msgSend的调用
id objc_msgSend(id self, SEL op, ...);
- 它首先找到 SEL 对应的方法实现 IMP。因为不同的类对同一方法可能会有不同的实现,所以找到的 方法实现依赖于消息接收者的类型。
如何查找IMP?
1,首先去该类的方法 cache 中查找,如果找到了就返回它;
2,如果没有找到,就去该类的方法列表中查找。如果在该类的方法列表中找到了,则将 IMP 返回,并将 它加入 cache中缓存起来。根据最近使用原则,这个方法再次调用的可能性很大,缓存起来可以节省下次 调用再次查找的开销。
3,如果在该类的方法列表中没找到对应的 IMP,在通过该类结构中的 super_class指针在其父类结构的方法列表中去查找,直到在某个父类的方法列表中找到对应的 IMP,返回它,并加入 cache 中;
4,如果在自身以及所有父类的方法列表中都没有找到对应的 IMP,则看是不是可以进行动态方法决议;
5,如果动态方法决议没能解决问题
- 然后将消息接收者对象(指向消息接收者对象的指针)以及方法中指定的参数传递给方法实现 IMP。
- 将方法实现的返回值作为该函数的返回值返回。
https://blog.csdn.net/kuangdacaikuang/article/details/53445960