6.4.拦截并替换方法

在程序当中,假设XiaoMing的中有test1这个方法,但是由于某种原因,我们要改变这个方法的实现,但是又不能去动它的源代码(正如一些开源库出现问题的时候),这个时候runtime就派上用场了。

我们先增加一个tool类,然后写一个我们自己实现的方法-change, 通过runtime把test1替换成change。

Class PersionClass = object_getClass([Person class]);
Class toolClass = object_getClass([tool class]);

    ////源方法的SEL和Method

    SEL oriSEL = @selector(test1);
    Method oriMethod = class_getInstanceMethod(PersionClass, oriSEL);

    ////交换方法的SEL和Method

    SEL cusSEL = @selector(change);
    Method cusMethod = class_getInstanceMethod(toolClass, cusSEL);

    ////先尝试給源方法添加实现,这里是为了避免源方法没有实现的情况

    BOOL addSucc = class_addMethod(PersionClass, oriSEL, method_getImplementation(cusMethod), method_getTypeEncoding(cusMethod));

    if (addSucc) {
          // 添加成功:将源方法的实现替换到交换方法的实现
        class_replaceMethod(toolClass, cusSEL, method_getImplementation(oriMethod), method_getTypeEncoding(oriMethod));

    }else {
    //添加失败:说明源方法已经有实现,直接将两个方法的实现交换即
method_exchangeImplementations(oriMethod, cusMethod);
  }