Runtime的使用2 【method swizzling】

method swizzling 不想再多说什么了。
IT.jpg

但是网上对于此的讲述大都是文绉绉、理解起来不是那么随性…特此稍微记一下,方便大家理解。代码贴一下,好参照对比一下。

悠哉.gif

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

@implementation UIImage (hook)

+ (void)load {

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        Class selfClass = object_getClass([self class]);

        SEL oriSEL = @selector(imageNamed:);
        Method oriMethod = class_getInstanceMethod(selfClass, oriSEL);

        SEL cusSEL = @selector(myImageNamed:);
        Method cusMethod = class_getInstanceMethod(selfClass, cusSEL);


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

        if (addSucc) {
            class_replaceMethod(selfClass, cusSEL, method_getImplementation(oriMethod), method_getTypeEncoding(oriMethod));
        }else {
            method_exchangeImplementations(oriMethod, cusMethod);
        }

    });
}
+ (UIImage *)myImageNamed:(NSString *)name {

    NSString * newName = [NSString stringWithFormat:@"%@%@", @"new_", name];
    return [self myImageNamed:newName];
}

@end
Method class_getClassMethod(Class cls , SEL name)        //是获取某个类的类方法。
Method class_getInstanceMethod(Class cls , SEL name)    //是获取某个类的实例方法。
BOOL class_addMethod(Class cls, SEL name, IMP imp,  const char *types)
//SEL : 类成员方法的指针,但不同于C语言中的函数指针,函数指针直接保存了方法的地址,但SEL只是方法编号。
//IMP:一个函数指针,保存了方法的地址。

【For example 】
比方我有一只狗,不知道能不能吃、不知道能不能游泳。(就是那么愚蠢…)
但是我突发奇想,让他吃的时候,他就去游泳。
奸笑.jpg

Step1:
首先我让他吃的时候直接执行游泳的实现。
BOOL addSucc = class_addMethod(selfClass, oriSEL, method_getImplementation(cusMethod), method_getTypeEncoding(cusMethod));

(1)如果成功了。那么这确实是个玩具狗。
本身不会吃,我给了吃的buff。并且让它吃的指令,它就去游泳…
那么把它的游泳改成吃就OK这里写代码片了。
class_replaceMethod(selfClass, cusSEL, method_getImplementation(oriMethod), method_getTypeEncoding(oriMethod));

(2)如果失败了。说明这是个真狗。以前就可以吃,再添加吃的实现失败。
我只需要交换下吃和游泳的imp。吃 <==> 游泳
method_exchangeImplementations(oriMethod, cusMethod);
当然了,游泳这个方法有啥操作就不那么重要了。可以让它真去游泳,也可以无操作…

似乎达成了共识.jpg

Ps:刚才脑袋短路,竟然想为啥用 class_replaceMethod 不用method_exchangeImplementations….
截止到刚才。吃 -> 游泳 如果我用method_exchangeImplementations,不就又把吃 -> 吃了吗…
掩面.jpg

希望可以帮助大家更加幽默的理解Method Swizzling

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值