一、hook实例函数
这个是我们比较常见的,执行之后,test1函数就指向hooktest1了
Class originalClass = objc_getClass("ViewControllerA");
SEL originalSelector = @selector(test1);
SEL swizzledSelector = @selector(hooktest1);
// 若originalClass已经存在test1方法,则返回NO
Method originalMethod = class_getInstanceMethod(originalClass, originalSelector);
Method swizzledMethod = class_getInstanceMethod(originalClass, swizzledSelector);
BOOL didAddMethod = class_addMethod(originalClass,originalSelector,method_getImplementation(swizzledMethod),method_getTypeEncoding(swizzledMethod));
// 若原来的方法并不存在,则添加即可
if (didAddMethod) {
class_replaceMethod(originalClass,swizzledSelector,method_getImplementation(originalMethod),method_getTypeEncoding(originalMethod));
}
method_exchangeImplementations(originalMethod, swizzledMethod);
有一个问题,上面的做法是hook这个类的A函数指向B函数,如何hook这个类的A函数指向另一个类的B函数呢?代码修改如下
Class originalClass = objc_getClass("ViewControllerA");
Class swizzledClass = objc_getClass("ViewControllerB");
SEL originalSelector = @selector(test1);
SEL swizzledSelector = @selector(hooktest1);
// 若originalClass已经存在test1方法,则返回NO
Method originalMethod = class_getInstanceMethod(originalClass, originalSelector);
Method swizzledMethod = class_getInstanceMethod(swizzledClass, swizzledSelector);
BOOL didAddMethod = class_addMethod(swizzledClass,originalSelector,method_getImplementation(swizzledMethod),method_getTypeEncoding(swizzledMethod));
// 若原来的方法并不存在,则添加即可
if (didAddMethod) {
class_replaceMethod(originalClass,swizzledSelector,method_getImplementation(originalMethod),method_getTypeEncoding(originalMethod));
}
method_exchangeImplementations(originalMethod, swizzledMethod);
二、hook类函数
实例函数和类函数,主要不同点在于class_getInstanceMethod
和class_getClassMethod
,下面是hook类函数的写法。
Class originalClass = objc_getClass("ViewControllerA");
Class swizzledClass = objc_getClass("ViewControllerB");
SEL originalSelector = @selector(test2);
SEL swizzledSelector = @selector(hooktest2);
// 若originalClass已经存在test2方法,则返回NO
Method originalMethod = class_getClassMethod(originalClass, originalSelector);
Method swizzledMethod = class_getClassMethod(swizzledClass, swizzledSelector);
BOOL didAddMethod = class_addMethod(swizzledClass,originalSelector,method_getImplementation(swizzledMethod),method_getTypeEncoding(swizzledMethod));
// 若原来的方法并不存在,则添加即可
if (didAddMethod) {
class_replaceMethod(originalClass,swizzledSelector,method_getImplementation(originalMethod),method_getTypeEncoding(originalMethod));
}
method_exchangeImplementations(originalMethod, swizzledMethod);
还有一个不同点,就是在不同类的情况下,hook之后的函数,如果要调用原函数,实例函数的,只需要如下
- (void)hooktest1 {
[self hooktest1];
}
但是,hook之后的类函数,需要这样调用原函数
+ (void)hooktest2 {
[objc_getClass("ViewControllerB") hooktest2];
}
基本上就这些了,用的好就很方便了。