首页 > 代码库 > Method Swizzling 改变selector的方式

Method Swizzling 改变selector的方式

在没有一个类的实现源码的情况下,想改变其中一个方法的实现,除了继承它重写、和借助类别重名方法暴力抢先之外,还有更加灵活的方法吗?在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;}

 

Method Swizzling 改变selector的方式