在没有一个类的实现源码的情况下,想改变其中一个方法的实现,除了继承它重写、和借助类别重名方法暴力抢先之外,还有更加灵活的方法吗?在Objective-C编程中,如何实现hook呢?
在Objective-C中调用一个方法,其实是向一个对象发送消息,查找消息的唯一依据是selector的名字。利用Objective-C的动态特性,可以实现在运行时偷换selector对应的方法实现,达到给方法挂钩的目的。
每个类都有一个方法列表,存放着selector的名字和方法实现的映射关系。IMP有点类似函数指针,指向具体的Method实现
我们可以利用 method_exchangeImplementations 来交换2个方法中的IMP,
我们可以利用 class_replaceMethod 来修改类,
我们可以利用 method_setImplementation 来直接设置某个方法的IMP,
……
归根结底,都是偷换了selector的IMP,
具体方法如下
+ (BOOL)swizzleMethod:(SEL)origSelector withMethod:(SEL)newSelector { Method origMethod = class_getInstanceMethod(self, origSelector); Method newMethod = class_getInstanceMethod(self, newSelector); if (origMethod && newMethod) { if (class_addMethod(self, origSelector, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) { class_replaceMethod(self, newSelector, method_getImplementation(origMethod), method_getTypeEncoding(origMethod)); } else { method_exchangeImplementations(origMethod, newMethod); } return YES; } return NO; }
时间: 2024-10-27 07:57:36