美文网首页
runtime方法交换

runtime方法交换

作者: 85ca4232089b | 来源:发表于2020-03-27 14:34 被阅读0次

#import "UIImage+customer.h"
#import <objc/runtime.h>

@implementation UIImage (customer)
+ (void)load{

    /**
     *  我们在这里使用class_addMethod()函数对Method Swizzling做了一层验证,如果self没有实现被交换的方法,会导致失败。
     *  而且self没有交换的方法实现,但是父类有这个方法,这样就会调用父类的方法,结果就不是我们想要的结果了。
     *  所以我们在这里通过class_addMethod()的验证,如果self实现了这个方法,class_addMethod()函数将会返回NO,我们就可以对其进行交换了。
     */

        Class class2 = object_getClass(self);
    
    /**
     * 对象方法是依实例方法的形式存在类当中的。 [self class]
     * 类方法是依实例方法的形式存在元类当中的   class2
     */
    [self hookClass:class2 originalSelector:@selector(swizzlingImageName:) swizzledSelector:@selector(imageNamed:)];
    [self hookClass:[self class] originalSelector:@selector(swizzlingInitWithData:) swizzledSelector:@selector(initWithData:)];

}
+ (void)hookClass:(Class)classObject originalSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector {
    Class class = classObject;
    //第三版Hook核心思想是,
    //如果本类中有 originalSelector 方法,直接交换。
    //如果本类中没有 originalSelector 方法,添加父类的的方法到子类,然后再直接交换。
    
    // 这两行与以前没有任何变化
    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
    
    //class_addMethod 添加的SEL是 originalSelector ,IMP 是 method_getImplementation(originalMethod),我称他们为原配,
    //如果本类中,已经有 originalSelector,再添加 originalSelector, 肯定返回NO,添加失败,那就直接交换了,跟第一版hook流程一模一样了,
    //如果本类中,没有此SEL,那就会去父类里找,返回的就是父类里的信息,然后将父类的信息,添加到本类中,就相当于,本类完全的继承了父类的方法,
    BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
    if (didAddMethod) {
        //添加成功后,本类中,已经有一个originalSelector方法了
        //我们第一次获得originalMethod是返回父类的originalMethod
        //我们需要再重新获得一下originalMethod,这次返回的不是父类的originalMethod
        //而是我们刚刚class_addMethod添加的到本类的originalMethod
        
        originalMethod = class_getInstanceMethod(class, originalSelector);
    }
    
    //走到这,就证明了,本类中肯定已经有这两个方法了,那就这样直接交换吧。
    method_exchangeImplementations(swizzledMethod, originalMethod);
}
+ (instancetype)swizzlingImageName:(NSString*)name{


    name = [NSString stringWithFormat:@"test_1"];
    return [self swizzlingImageName:name];
}
- (instancetype)swizzlingInitWithData:(NSData*)data{

    NSLog(@"===========");
    return [self swizzlingInitWithData:data];
}
@end

相关文章

  • runtime

    runtime交换方法 动态添加方法

  • runTime常用方法

    使用runTime改变实例成员的值 使用runtime来交换两个方法 注意再次调用该方法不交换 使用runTime...

  • Runtime

    runtime运行时机制1:通过runtime,实现方法交换(交换两个类方法、交换两个实例方法)2:通过runti...

  • Day3

    1 runtime运行时机制1:通过runtime,实现方法交换(交换两个类方法、交换两个实例方法)。2:通过ru...

  • runtime的理解(二)

    主要内容 利用 runtime 交换方法 利用 runtime 动态添加方法 利用 runtime 动态添加属性 ...

  • 查看SDK调用支付宝参数

    使用runtime 方法交换openurl

  • objc runtime (四)动态添加属性

    在《objc runtime (二)交换方法》中我提到过runtime最实用的就是交换方法和动态添加属性两个用法。...

  • iOS runtime如何交换两个类方法

    如有转载,请标明出处:iOS runtime如何交换两个类方法 runtime交换实例方法,老生常谈的问题,很多b...

  • iOS -- runtime的应用

    runtime主要有一下几种应用场景 方法交换 添加属性 (一)方法交换 (1)字体适配 方法交换实际交换的是方法...

  • runtime和oc内存区域(2018-04-02)

    runtime常用的几个方法: 交换方法 动态添加属性 动态添加方法 1.交换方法 class_getClassM...

网友评论

      本文标题:runtime方法交换

      本文链接:https://www.haomeiwen.com/subject/wvmluhtx.html