Runtime 运行时的方法交换
来源:互联网 发布:video sharing软件 编辑:程序博客网 时间:2024/06/05 11:12
最近看了一个Runtime 的东西,”方法欺骗”(IMP 方法的交换).
使用好了非常厉害.
NSString * str = @"http://baidu.com李"; NSURL * url = [NSURL URLWithString:str]; NSLog(@"1----%@",url);打印:2017-09-14 17:45:41.777 Runtime[4402:1147114] 1----(null)
这里出现nil 是因为 字符串包含中文,导致转成URL时不识别.
可以UTF-8 转码处理
NSString* string2 = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
但是每次出现一个URL 你都要这样处理,显然是很麻烦的.
就算你写在类别里面处理,使用的地方你要导入头文件,使用新加的类别方法.新项目还ok,但是你要改写别人的代码你会疯掉的.
下面要介绍使用runtime 来处理这个事情
还是要新建类别的 如:NSURL 的类别
引用#import <objc/runtime.h> Runtime的头文件
#import "NSURL+url.h"#import <objc/runtime.h>@implementation NSURL (url)
这里是你新加的类别方法来做处理
+(instancetype)strURL:(NSString *)str { NSURL * url = [NSURL URLWithString:str]; if (url == nil) { NSLog(@"url 为空"); } return url;}
我们希望在外面还调用下面这个系统方法,但是希望内部走上面那个处理方法
[NSURL URLWithString:str];
ok,其实一个类被内存装载时,会调用一个方法: +(void)load
在这里做他们两个的方法交换处理
// 这个类被装载的时候调用 进入内存的时候调用+(void)load { // 交换方法的IMP /* <#Method m1#> 要交换的方法1 <#Method m2#> 要交换的方法2 method_exchangeImplementations(<#Method m1#>, <#Method m2#>) 得到一个类方法 class_getClassMethod([self class], @selector(URLWithString:)); 得到一个实例方法 class_getInstanceMethod(<#__unsafe_unretained Class cls#>, <#SEL name#>) */ Method url = class_getClassMethod([self class], @selector(URLWithString:)); Method strUrl = class_getClassMethod([self class], @selector(strURL:) ); method_exchangeImplementations(url, strUrl);}
这时候两个方法已经交换完了,但是你自己新加的类方法: +(instancetype)strURL:(NSString *)str
内部实现还是有 : NSURL * url = [NSURL URLWithString:str];
会造成死循环.你应该这样:
#import "NSURL+url.h"#import <objc/runtime.h>@implementation NSURL (url)// 这个类被装载的时候调用 进入内存的时候调用+(void)load { // 交换方法的IMP /* <#Method m1#> 要交换的方法1 <#Method m2#> 要交换的方法2 method_exchangeImplementations(<#Method m1#>, <#Method m2#>) 得到一个类方法 class_getClassMethod([self class], @selector(URLWithString:)); 得到一个实例方法 class_getInstanceMethod(<#__unsafe_unretained Class cls#>, <#SEL name#>) */ Method url = class_getClassMethod([self class], @selector(URLWithString:)); Method strUrl = class_getClassMethod([self class], @selector(strURL:) ); method_exchangeImplementations(url, strUrl);}+(instancetype)strURL:(NSString *)str { 注意:这里一定要写好注释,不然别人看到... NSURL * url = [NSURL strURL:str]; // 这里用到的IMP 方法交换 这个方法已经是 URLWithString if (url == nil) { NSLog(@"url 为空"); } return url;}@end
这里已经ok了.外面依然是使用系统的方法,但内部是走的自己新加的方法.
阅读全文
1 0
- Runtime 运行时的方法交换
- 运行时(runtime)-方法交换
- XZ_iOS之Runtime使用运行时交换方法
- RunTime交换方法的实现
- Runtime - 运行时 理解和应用 字典转模型框架 AFN中的交换方法
- Runtime的实践——方法交换
- runtime交换方法的正确姿势
- runtime交换方法的正确姿势
- runtime 方法交换
- runtime 方法交换
- Runtime -- 交换方法
- runtime交换方法
- runtime方法交换
- Runtime 学习-方法交换
- runtime 方法交换
- 运行时动态方法交换
- runtime运行时 isa指针 SEL方法选择器 IMP函数指针 Method方法 runtime消息机制 runtime的使用
- ios runtime 交换方法实现
- Dynamics CRM中构建查询
- 【安全牛学习笔记】操作系统识别
- java hash碰撞分析模拟
- 08.node+express+mongo form 提交(继07讲继续整合)
- 守夜人 带权并查集
- Runtime 运行时的方法交换
- Java 单循环打印九九乘法表
- 【错误解决】有关发送邮件带附件的错误
- The Little Girl who Picks Mushrooms
- [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher J (kmp扩展)
- JS正则表达式 ,reg.test()时,慎重全局查找/.../g属性
- 关于property文件的使用
- 【安全牛学习笔记】SMB扫描
- 原型模式