免费开源的iOS开发学习平台

Runtime简介:4-替换类中原有方法的实现

在实际的开发过程中,针对已经封装过的第三方SDK,假如有些方法的实现有Bug,因为代码已经被封装,因而无法直接修改源代码,只能通过Runtime来去替换原来的方法。当调用原方法时,使用新方法来直接替换执行,从而达到拦截方法执行的目的。

准备工作

首先定义一个Tool类,其中有一个repair方法,执行后,会打印一行日志,如下所示。

  • Too.h
@interface Tool : NSObject
-(void) repair;
@end
  • Tool.m
#import "Tool.h"
@implementation Tool
-(void) repair{
    NSLog(@"1 -- repair method in <%@> class", [self class]);
}
@end

再定义一个MYTool类,其中有一个my_repair方法,执行后,会打印一行日志,如下所示。

  • MYTool.h
#import <Foundation/Foundation.h>
@interface MYTool : NSObject
-(void) my_repair;
@end
  • MYTool.m
#import "MYTool.h"
@implementation MYTool
-(void) my_repair{
    NSLog(@"2 -- repair method in <%@> class", [self class]);
}
@end

使用Runtime实现方法替换

接下来,我们使用Runtime中的method_exchangeImplementations()方法,把Tool类中的repair方法,替换成MYTool类中的my_repair方法。

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Tool *tool = [Tool new];
        [tool repair];
        /*替换Tool中的方法*/
        Method oldM = class_getInstanceMethod([Tool class], @selector(repair));
        Method newM = class_getInstanceMethod([MYTool class], @selector(my_repair));
        method_exchangeImplementations(oldM, newM);
        //再次执行repair方法
        [tool repair];   
    }
    return 0;
}

运行结果如下。可以看到替换后,执行的是MYTool类中定义的my_repair方法,而调用的类是Tool类,即Tool类中的repair方法被替换了。