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

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

时间: 2024-11-05 20:48:06

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

Python面向切面编程-语法层面和functools模块

1,Python语法层面对面向切面编程的支持(方法名装饰后改变为log) __author__ = 'Administrator' import time def log(func): def wrapper(*args): start = time.time() func(args) end =time.time() print 'func used time is :', end - start return wrapper @log def reg(args): print 'welcom

iOS开发——高级特性&amp;Runtime运行时特性详解

Runtime运行时特性详解 本文详细整理了 Cocoa 的 Runtime 系统的知识,它使得 Objective-C 如虎添翼,具备了灵活的动态特性,使这门古老的语言焕发生机.主要内容如下: 引言 简介 与Runtime交互 Runtime术语 消息 动态方法解析 消息转发 健壮的实例变量(Non Fragile ivars) Objective-C Associated Objects Method Swizzling 总结 引言 曾经觉得Objc特别方便上手,面对着 Cocoa 中大量

runtime 运行时机制 完全解读

runtime 运行时机制 完全解读 目录[-] import import 我们前面已经讲过一篇runtime 原理,现在这篇文章主要介绍的是runtime是什么以及怎么用!希望对读者有所帮助! 首先,第一个问题, 1>runtime实现的机制是什么,怎么用,一般用于干嘛? 这个问题我就不跟大家绕弯子了,直接告诉大家, runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API. 在我们平时编写的OC代码中, 程序运行过程时, 其实最终都是转成了runti

?runtime 运行时机制

?runtime 运行时机制 完全解读 摘要 在最开始听到runtime的时候,我是感到恐惧的,多么高大上的东西啊!!!后来,开始在网上查一些资料,可是就是只有那么几篇,看了好久,还不知所云,所以就更加恐惧了!!!!后来经过查看documents 以及一些国外大牛的blogs,终于对runtime有了更深刻的了解!于是就想写下这些东西,希望对读者们有帮助…… runtime 运行时机制 详细解读 目录[-] import import 我们前面已经讲过一篇runtime 原理,现在这篇文章主要介

iOS的runtime运行时机制

本文转自http://www.cnblogs.com/guoxiao/p/3583432.html 最近一直在研究runtime运行时机制的问题,我想可能也有很多人不太清楚这个问题吧?在这里跟大家沟通分享下我对与runtime机制的理解. 要理解runtime,首先我们要了解类和对象的内部结构,下面将首先介绍下OC中类与对象的结构层次. 一.首先,从 runtime.h头文件中找到对 class 与 object 的定义 /// An opaque type that represents an

Spring AOP:面向切面编程,AspectJ,是基于spring 的xml文件的方法

导包等不在赘述: 建立一个接口:ArithmeticCalculator,没有实例化的方法: package com.atguigu.spring.aop.impl.panpan; public interface ArithmeticCalculator { //创建一个接口,其是抽象的类,不能实例化 int add(int i,int j); int sub(int i,int j); int mul(int i,int j); int div(int i,int j); } 建立一个类:A

使用Spring进行面向切面编程(AOP)

转载于http://www.blogjava.net/supercrsky/articles/174368.html 文章太长,写的很好,没看完,转过来慢慢理解,品味 简介 面向切面编程(AOP)提供另外一种角度来思考程序结构,通过这种方式弥补了面向对象编程(OOP)的不足. 除了类(classes)以外,AOP提供了 切面.切面对关注点进行模块化,例如横切多个类型和对象的事务管理. (这些关注点术语通常称作 横切(crosscutting) 关注点.) Spring的一个关键的组件就是 AOP

Java 面向切面编程 AOP

本文内容 实例 引入 原始方法 装饰者模式 JDK 动态代理和 cglib 代理 直接使用 AOP 框架 下载 demo 实例 引入 package com.cap.aop;   public interface ICalculator { public double add(double num1, double num2) throws Exception;   public double sub(double num1, double num2) throws Exception;   p

Android面向切面编程(AOP)(转)

转自:https://www.jianshu.com/p/aa1112dbebc7 一.简述 1.AOP的概念 如果你用java做过后台开发,那么你一定知道AOP这个概念.如果不知道也无妨,套用百度百科的介绍,也能让你明白这玩意是干什么的: AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍