在学习Runtime的过程中,很多概念性的文章看得晕头转向,总结一下,结合实战进行讲解,希望对你有一点帮忙。
首先说说Runtime的功能:
1)字典转model
在开发中,对于处理网络请求中获取的数据(即把请求到的json或字典转换成方便使用的数据模型)是我们在开发中必不可少的操作。诸如强大的第三方MJExtension、JSONModel、JSONExport或者YYModel是我们所熟知的框架,因为它们使用起来简单方便,简单到有时候一句代码就可以实现我们所需要的字典和模型之间的转换。由于这些自动化框架,这里就不过多讲解了,有兴趣的小伙伴可以移步Runtime实现iOS字典转模型。
2)归档解档
归档和解档需要对每个属性都实现一遍encodeObject:forKey:和decodeObjectForKey:方法,这样就会显得比较繁琐,但是我们可以利用Runtime获取所有属性来重写归档解档方法。
创建一个NSObject的分类@interface NSObject (Runtime):

归档的.m中的协议方法中分别调用这两个方法:

很简单看一下例子就懂了,就不做过多解释。附Runtime归档解档demo
3)拦截系统自带的方法调用(Swizzle 黑魔法),也可以说成对系统的方法进行替换,比如拦截imageNamed:、viewDidLoad、alloc
需求:比如iOS6 升级 iOS7 后需要版本适配,根据不同系统使用不同样式图片(拟物化和扁平化),如何通过不去手动一个个修改每个UIImage的imageNamed:方法就可以实现为该方法中加入版本判断语句?
步骤:
1、为UIImage建一个分类(UIImage+Category)
2、在分类中实现一个自定义方法,方法中写要在系统方法中加入的语句,比如版本判断[参考 ]
+ (UIImage*)xh_imageNamed:(NSString*)name {
doubleversion = [[UIDevicecurrentDevice].systemVersiondoubleValue];
if(version >=7.0) {
// 如果系统版本是7.0以上,使用另外一套文件名结尾是‘_os7’的扁平化图片
name = [name stringByAppendingString:@"_os7"]; }
return[UIImagexh_imageNamed:name];
}
3、分类中重写UIImage的load方法,实现方法的交换(只要能让其执行一次方法交换语句,load再合适不过了)
+ (void)load {
// 获取两个类的类方法
Method m1 = class_getClassMethod([UIImageclass],@selector(imageNamed:));
Method m2 = class_getClassMethod([UIImageclass],@selector(xh_imageNamed:));
// 开始交换方法实现
method_exchangeImplementations(m1, m2);
}
注意:自定义方法中最后一定要再调用一下系统的方法,让其有加载图片的功能,但是由于方法交换,系统的方法名已经变成了我们自定义的方法名(有点绕,就是用我们的名字能调用系统的方法,用系统的名字能调用我们的方法),这就实现了系统方法的拦截!
利用以上思路,我们还可以给 NSObject 添加分类,统计创建了多少个对象,给控制器添加分类,统计有创建了多少个控制器,特别是公司需求总变的时候,在一些原有控件或模块上添加一个功能,建议使用该方法!
4)万能控制器跳转
在开发项目中,可能会遇到这样变态的需求:
推送:根据服务端推送过来的数据规则,跳转到对应的控制器。
最开始的想法是,写个switch,考虑所有的跳转因素,缺陷:如果有新需求跳转未在switch中的跳转因素需要发版本。
偶然翻看Runtime,发现可以利用runtime动态生成对象、属性、方法这特性。那么久开干。
1、根据推送规则跳转对应界面

2、推送过来的消息规则
模拟服务器返回的数据:

3、跳转界面

4、检测对象是否存在该属性

代码demo:RuntimeJumpVC
网友评论