OC 运行时机制的一些应用
2016-03-15 00:10
316 查看
前言
OC 的运行时机制(Runtime)这个词接触过 iOS 开发的人或多或少应该都听说过,有的人已经能够熟练掌握它的真谛,有的对其依然感觉神秘无比。诚然,即使不掌握 OC 的运行时机制并不影响开发者开发出优秀的 iOS 应用,但是了解运行时机制能够帮助开发者更加透彻的了解 OC 背后的故事,揭开高级语言壳子下面的东西。应用场景
动态添加属性
我们都知道,分类(Category)是 OC 的一个重要的语法,它可以帮助开发者在类的外部扩充方法,保持原类的规模,方法在需要的时候分块声明和实现,然而 Category 并不能帮助我们方便的给原来的类扩充属性,如果我们在分类中如下添加属性:会出现如下错误:
而利用 objc/runtime.h 库中的一些函数可以帮助我们在分类添加属性,具体如下:
这种应用场景在 SDWebImage 框架中多次出现,SDWebImage 框架大量使用了分类来给 UIKit 框架的种类扩充方法,而在有些情况下又不得不通过分类给原类扩充属性来达到框架的设计目的,比如:我们可以在
UIImageView+WebCache.m中找到这样的使用场景:
动态检测模型属性
使用 KVC 进行字典转模型的时候,我们一般都会这样写:
这样写会有一个缺陷,就是当 server 返回的 json 数据比转成字典后属性比我们定义的模型属性多的时候,KVC 转换的时候会报
undefined key错误,我们可以重写
改写原来方法默认的报异常的实现方式,这样就不会报错误。
其实,除这个方法进行字典转模型以外,我们可以使用运行时的一些方法动态的获取模型中的属性列表:
然后根据获得属性列表进行有针对性的赋值,达到字典转模型的目的:
这个方法也在 MJExtension 框架有所涉及,
NSObject+MJProperty.m中的
+ (NSMutableArray *)properties方法使用了这种方式获取了属性列表。
方法的交换(拦截)
因为 OC 是动态的语言,方法的调用并不是在编译阶段完全定死的,而是在运行的时候以发送消息的形式进行调用,所以这里就引出了一个比较受争议的做法,就是通过运行时的 api 对方法的调用进行交换,也就是所谓的 method swizzling。我们通过下面的例子演示一下,将系统的[UIImage imageNamed:]的方法与我们自己实现的
imageWithName:方法进行交换:
这个地方需要注意的是:在自己写的需要交换的方法中,由于方法已经被交换了,不能在自己写的方法中使用imageNamed方法,否则会造成死循环。
修改对象中的私有属性
工作中可能会遇到一种情况,你的项目是一个维护有些时日的老项目,当有的时候实现一个功能需要修改基类中的一些属性,然而基类在定义的时候并未考虑到这个属性需要修改,所以在类扩展中进行的定义,没有暴露出来,由于考虑到基类在多个地方被使用,无法评估修改基类对于项目其他地方的影响,这个时候需要用运行时的机制对私有属性进行获取和修改:这个例子中就在没有破坏类结构的前提下修改了
DZOldNavigationController中的私有属性
_screenShotsList的值。
文/CoCodeDZ(简书作者)
原文链接:http://www.jianshu.com/p/b686c52a8d88
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
相关文章推荐
- MFC-俄罗斯方块
- libz.dylib的研究 libz.1.2.5.tbd
- Mvc设计模型与三层架构
- 蓝桥杯 牌型种数
- 第三周作业(三)
- kettle获取系统信息及输出
- 愚人并查集
- app程序的执行顺序
- Calculator Part Ⅰ
- Leetcode
- java开发_eclipse导出为war文件,热部署到tomcat运行总结
- java关键字总结
- java开发_jcrop_网页截图工具(插件)
- 欢迎使用CSDN-markdown编辑器
- 20160218.CCPP体系详解(0028天)
- QT异形图形的开发
- 花朵数_蓝桥杯题目
- js css+html实现简单的日历
- JSP自定义标签基础知识学习
- 索引与优化like查询