前言:
runtime的资料网上有很多了,但是大部分有些隐晦难懂,我通过自己的学习方法总结一遍,主要讲一些常用的方法功能,以实用为主。( runtime 必须要导入系统库 <objc/runtime.h> )
1. 动态的交换(类方法)
- (void)viewDidLoad {
[super viewDidLoad];
[SecMainViewController run];
[SecMainViewController jump];
//这打印的是跑和跳
MethodnewRun =class_getClassMethod([SecMainViewControllerclass],@selector(run));
MethodnewJump =class_getClassMethod([SecMainViewControllerclass],@selector(jump));
method_exchangeImplementations(newRun, newJump);
[SecMainViewController run];
[SecMainViewController jump];
//交换之后 打印的是跳 和 跑
}
+(void)run {
NSLog(@"跑");
}
+(void)jump {
NSLog(@"跳");
}
2.拦截系统方法(以动态适配屏幕字体和大小为例子)
步骤:
1、为UIFont建一个分类(UIFont+Category)
2、分类中重写UIFont的load方法,实现方法的交换(只要能让其执行一次方法交换语句,load再合适不过了)
// 获取替换后的类方法
Method newMethod =class_getClassMethod([self class],@selector(adjustFontName:size:));
// 获取替换前的类方法
Method method =class_getClassMethod([self class],@selector(fontWithName:size:));
// 然后交换类方法,交换两个方法的IMP指针,(IMP代表了方法的具体的实现)
method_exchangeImplementations(newMethod, method);
}
3.实行自定义的adjustFontName:size方法
+ (UIFont*)adjustFontName:(NSString*)name size:(CGFloat)fontSize{
UIFont*newFont =nil;
newFont = [UIFontadjustFontName:namesize:fontSize * [UIScreenmainScreen].bounds.size.width/MyUIScreen];
return newFont;
}
注意:自定义方法中最后一定要再调用一下系统的方法,让其有设置font的功能,但是由于方法交换,系统的方法名已经变成了我们自定义的方法名(有点绕,就是用我们的名字能调用系统的方法,用系统的名字能调用我们的方法),这就实现了系统方法的拦截!
3.在分类中设置属性,给任何一个对象设置属性
步骤:
1、创建一个分类,比如给任何一个对象都添加一个name属性,就是NSObject添加分类(NSObject+Category)
2、先在.h 中@property 声明出get 和 set 方法,方便点语法调用
@property(nonatomic,copy)NSString*name;
3、在.m 中重写set 和 get 方法,内部利用runtime 给属性赋值和取值
char nameKey;
- (void)setName:(NSString*)name {
// 将某个值跟某个对象关联起来,将某个值存储到某个对象中
objc_setAssociatedObject(self, &nameKey, name,OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString*)name {
return objc_getAssociatedObject(self,&nameKey)
}
4.实现字典和模型的自动转换
(核心就是可以遍历出字典中的每个属性,json解析中大牛框架都用了这个特性,包括MJEXtension,YYModel,jsonModel都是将json转换为字典,再遍历字典中的每个属性来进行modle的转换)
5.实现万能控制器跳转
产品来一变态需求,推送过来的消息,要跳转到任意控制器.利用runtime动态生成对象、属性、方法这特性,我们可以先跟服务端商量好,定义跳转规则,比如要跳转到A控制器,需要传属性id、type,那么服务端返回字典给我,里面有控制器名,两个属性名跟属性值,客户端就可以根据控制器名生成对象,再用kvc给对象赋值,这样就搞定了
6.Jspath 热更新
使用运行时,jspatch 基本上算是黑科技,在线修复版本bug,微信都使用了这个技术,详情百度“JSPatch”,此处省略30000字
总结了几种常见runtime使用,希望对大家有帮助
作者:HuaHuo
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
网友评论