返回

剖析msgSend底层原理,揭秘动态方法决议的奥秘

IOS

msgSend的初识

在Objective-C中,消息发送是一种非常重要的机制,它允许对象之间进行交互。消息发送的底层实现是msgSend函数。msgSend函数的作用是将消息发送给某个对象,并执行相应的方法。

msgSend函数的第一个参数是接收消息的对象,第二个参数是消息选择器,第三个参数是消息的参数列表。当msgSend函数被调用时,它会首先在接收消息的对象中查找与消息选择器相匹配的方法。如果找到匹配的方法,则执行该方法。如果没有找到匹配的方法,则会继续在该对象的父类中查找,直到找到匹配的方法为止。如果在整个继承链中都没有找到匹配的方法,则会引发一个unrecognized selector异常。

动态方法决议

动态方法决议是Objective-C中的一项重要特性,它允许在运行时确定要调用的方法。这使得Objective-C可以实现非常灵活的编程方式。

动态方法决议的实现依赖于msgSend函数。当msgSend函数在接收消息的对象中找不到与消息选择器相匹配的方法时,它会调用该对象的methodForSelector方法。methodForSelector方法的作用是查找与消息选择器相匹配的方法。如果methodForSelector方法找到匹配的方法,则返回该方法。如果没有找到匹配的方法,则返回nil。

如果methodForSelector方法返回nil,则msgSend函数会调用该对象的forwardInvocation方法。forwardInvocation方法的作用是将消息转发给另一个对象。forwardInvocation方法可以用来实现消息的转发。

经典案例

在Objective-C中,有一个经典的案例叫做“unrecognized selector sent to instance xxx”。这个错误通常是由于在对象中找不到与消息选择器相匹配的方法而引起的。

为了解决这个问题,可以重写methodForSelector方法。在methodForSelector方法中,可以动态地生成与消息选择器相匹配的方法。这样,当msgSend函数在对象中找不到与消息选择器相匹配的方法时,它会调用methodForSelector方法。methodForSelector方法会动态地生成一个与消息选择器相匹配的方法,并返回该方法。这样,就可以避免“unrecognized selector sent to instance xxx”错误的发生。

总结

msgSend函数是Objective-C中消息发送的底层实现。动态方法决议是Objective-C中的一项重要特性,它允许在运行时确定要调用的方法。msgSend函数和动态方法决议共同实现了Objective-C灵活的编程方式。