Runtime的使用2 【method swizzling】

来源:互联网 发布:重生之女土匪知乎 编辑:程序博客网 时间:2024/06/10 19:30

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

原创粉丝点击