p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Yuanti SC"; color: #ff2600; background-color: #ffffff }
p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Yuanti SC"; color: #919191; background-color: #ffffff }
p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Yuanti SC"; color: #008400; background-color: #ffffff }
p.p4 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Yuanti SC"; color: #0433ff; background-color: #ffffff }
p.p5 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Yuanti SC"; color: #aa7942; background-color: #ffffff }
p.p6 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Yuanti SC"; color: #000000; background-color: #ffffff; min-height: 20.0px }
p.p7 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo; color: #aa7942; background-color: #ffffff }
p.p8 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo; color: #008400; background-color: #ffffff; min-height: 14.0px }
p.p9 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo; color: #d12f1b; background-color: #ffffff }
p.p10 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo; color: #000000; background-color: #ffffff }
p.p11 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Yuanti SC"; color: #000000; background-color: #ffffff }
p.p12 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "PingFang SC"; color: #008400; background-color: #ffffff }
p.p13 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo; color: #ff2600; background-color: #ffffff }
p.p14 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo; color: #ba2da2; background-color: #ffffff }
p.p15 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo; color: #0433ff; background-color: #ffffff }
p.p16 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo; color: #008400; background-color: #ffffff }
p.p17 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo; color: #000000; background-color: #ffffff; min-height: 14.0px }
span.s1 { color: #008400 }
span.s2 { color: #0433ff }
span.s3 { color: #000000 }
span.s4 { color: #aa7942 }
span.s5 { font: 14.0px "Yuanti SC"; color: #000000 }
span.s6 { font: 12.0px "PingFang SC" }
span.s7 { color: #703daa }
span.s8 { color: #3e1e81 }
span.s9 { color: #d12f1b }
span.s10 { color: #ba2da2 }
span.s11 { font: 12.0px Menlo }
span.s12 { color: #78492a }
span.s13 { font: 12.0px "PingFang SC"; color: #0433ff }
span.s14 { font: 12.0px "PingFang SC"; color: #ff2600 }
span.s15 { color: #ff2600 }
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
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Yuanti SC"; color: #aa7942; background-color: #ffffff }
p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Yuanti SC"; color: #008400; background-color: #ffffff; min-height: 20.0px }
p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Yuanti SC"; color: #d12f1b; background-color: #ffffff }
p.p4 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Yuanti SC"; color: #000000; background-color: #ffffff }
p.p5 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Yuanti SC"; color: #000000; background-color: #ffffff; min-height: 20.0px }
p.p6 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Yuanti SC"; color: #0433ff; background-color: #ffffff }
p.p7 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Yuanti SC"; color: #008400; background-color: #ffffff }
p.p8 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Yuanti SC"; color: #ff2600; background-color: #ffffff }
p.p9 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Yuanti SC"; color: #ba2da2; background-color: #ffffff }
span.s1 { color: #000000 }
span.s2 { color: #008400 }
span.s3 { color: #703daa }
span.s4 { color: #3e1e81 }
span.s5 { color: #d12f1b }
span.s6 { color: #ba2da2 }
span.s7 { color: #78492a }
span.s8 { color: #0433ff }
span.s9 { color: #ff2600 }
span.s10 { color: #aa7942 }
例子://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