运行时交换方法

2018/7/20 posted in  iOS
+(void)load{
    Class class = self;
    
    SEL fromSelector = @selector(viewDidLoad);
    
    SEL toSelector = @selector(mwviewDidLoad);

    Method fromMethod = class_getInstanceMethod(class, fromSelector);
    Method toMethod = class_getInstanceMethod(class, toSelector);
    
    if(class_addMethod(class, fromSelector, method_getImplementation(toMethod), method_getTypeEncoding(toMethod))) {
        class_replaceMethod(class, toSelector, method_getImplementation(fromMethod), method_getTypeEncoding(fromMethod));
    } else {
        method_exchangeImplementations(fromMethod, toMethod);
    }

    
}

-(void)mwviewDidLoad{
    
    NSLog(@"hello world from mwviewDidLoad");
    [self mwviewDidLoad];
    
}
- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"hello world from viewDidLoad");

    // Do any additional setup after loading the view, typically from a nib.
}

打印结果为

2019-03-26 15:06:35.542596+0800 ExchangeMethod[48714:4112036] hello world from mwviewDidLoad
2019-03-26 15:06:35.542847+0800 ExchangeMethod[48714:4112036] hello world from viewDidLoad

注意千万不能手误
千万不能把[self mwviewDidLoad];改成[self viewDidLoad];

因为交换方法只会交换一次,实现交换了方法,调用viewDidLoad的时候其实实际是调用的本身mwviewDidLoad,往下走就又会调用本身,造成死循环。