Runtime(运行时)002-方法欺骗(面向切面编程: 修改原来方法的调用顺序)

Method 成员方法  MethodSwizzling 方法欺骗

#import <objc/runtime.h> 苹果提供一套C语言的API,可以在OC编译运行的阶段,动态的进行操作

OC方法:

 1. SEL 方法的编号

 2. IMP 方法实现(本质上是函数指针!!)

 注意:在OC中我们调用方法都是通过消息机制,给某个对象,发送方法编号消息!!

 通过SEL可以找到对应的 IMP(方法实现)! SEL 和 IMP 是 一一对应的关系!

编程思想:面向切面编程  HOOK 思想

HOOK: 钩子- 修改原来的方法调用顺序!!本身给对象发送eat ,它居然跑到 run 方法了

 [p eat] -- objc_msgSend(p,@selector(eat));

 SEL: eat --- IMP : eat

 改变对应关系

 SEL: eat --- IMP : run

 

例子//NSURL 不检测是否为nil !! 我们给系统的NSURL 添加功能!! 

 

    NSURL * url = [NSURL URLWithString:@"http://www.baidu.com/中"];

    NSURLRequest * request = [NSURLRequest requestWithURL:url];

    NSLog(@"%@",request);

 

实现步骤

1->创建一个NSURL的类别

+(instancetype)HK_URLWithString:(NSString *)URLString;

2->.m实现文件中

//项目安装在手机上!是二进制(Math-o)!! Math-o 类似于 exe 放在硬盘上面的

//启动App 1. 将硬盘的二进制,加载进入内存!!(装载) .m 源文件

//HOOK: 在整个项目中,一旦你调用URLWithString ,就来到 HK_URLWithString (Runtime)

 

 

#import "NSURL+hook.h"

#import <objc/runtime.h>

@implementation NSURL (hook)

+(void)load {

    NSLog(@"Load..");//先执行 Load ,后执行Main函数

    //下钩子!! method_exchangeImplementations (A,B)  交换SEL 和IMP 的对应关系和指向

    /*

     SEL(目录) -- IMP(才是指针!)

     */

    //获取Method

    //class_getClassMethod     获取类方法

    //class_getInstanceMethod  获取对象/实例方法

    

    Method URLWithString = class_getClassMethod(self, @selector(URLWithString:));

    Method HK_URLWithString = class_getClassMethod(self, @selector(HK_URLWithString:));

    //method_exchangeImplementations

    //交换,下钩子

    method_exchangeImplementations(URLWithString, HK_URLWithString);

    

}

+ (instancetype)HK_URLWithString:(NSString *)URLString {

    NSURL * url = [NSURL HK_URLWithString:URLString];//递归 发送 URLWithString 消息 又调用 HK_URLWithString

    if (url==nil) {

        NSLog(@"url 为 nil !!!");

    }

    return url;

}

 

原文地址:https://www.cnblogs.com/StevenHuSir/p/Runtime_MethodSwizzling.html