跳到主要内容

IOS Runtime如何通过selector找到对应的IMP地址?

参考答案:

在iOS的Runtime系统中,每个类的方法都对应一个IMP(Implementation)地址,它指向实现该方法的函数。selector则是方法的名称或标识。通过selector找到对应的IMP地址,我们可以动态地调用或修改方法的行为。

你可以使用objc_msgSend函数的变种class_getMethodImplementationobjc_getImplementation来根据selector获取IMP地址。

以下是一些示例:

使用class_getMethodImplementation

如果你知道方法属于哪个类,你可以使用class_getMethodImplementation函数。这个函数需要一个类对象和一个selector作为参数,并返回对应方法的IMP地址。

Class cls = [YourClass class];
SEL selector = @selector(yourMethod);
IMP imp = class_getMethodImplementation(cls, selector);

使用objc_getImplementation

如果你不确定方法属于哪个类,或者你想获取实例方法的实现(而不仅仅是类方法),你可以使用objc_getImplementation函数。这个函数只需要一个selector作为参数。

SEL selector = @selector(yourMethod);
IMP imp = objc_getImplementation(selector);

请注意,objc_getImplementation返回的是第一个在类继承层次中找到的方法的实现。如果该方法在子类中被重写,那么它返回的是子类中的实现,而不是父类中的实现。

一旦你有了IMP地址,你可以将其转换为函数指针,并直接调用它。但是,请注意,直接操作IMPobjc_msgSend是底层和复杂的,需要谨慎处理,并且可能会引入未定义的行为或崩溃。在大多数情况下,你应该使用Objective-C的消息传递机制(例如[object method])来调用方法,而不是直接操作IMP