看完本篇之后你将获得:
Runtime是开源的,任何时候你都可以从http://opensource.apple.com获取。事实上查看 Objective-C 源码是我理解它是如何工作的第一种方式,在某些问题上要比读苹果的文档要好。 引言 相信很多从事iOS开发的小伙伴们都听过这样一句形容runtime的话:
这句话是某知名培训机构内某老师对学生们说的一句话,相信不少人尤其是初学的萌新们还没了解过runtime,听了这句话就被吓到了!直接在心里给runtime打个一打标签[危险,慎用,底层,难,用不到,不用掌握]。以至于很多人做了有一段时间的iOS开发却依然对其一知半解…… 定义
其实就在下个人的理解:runtime就是丫Objective-C 的灵魂!Objective-C之所以叫Objective-C是因为他比C语言不同,是面向对象的。但是Objective-C为什么有面相对象的能力?就是因为有runtime这个鬼东西! 进阶 我们为什么要学习runtime?
其实runtime所能做的还不止这些,你甚至可以利用它来把一个Class A的实例对象a在程序中当作Class B的实例对象来用。所以很多iOS开发者把runtime叫做obj-C的黑魔法! 常用方法 先来个最简单最基本的也是几乎所有runtime文必备的例子:
很多初学者除了知道runtime把对象的方法调用转化成消息发送的代码之后就不知道其他的了,但是显然仅仅知道上述的转化并没有什么“吡-”用,我们来看runtime中比较常用(实用)的几种基本用法:
首先定义一个简单的类Person
然后在需要遍历对象的属性时
这时就会打印出这个类对象的属性相关信息:
[消息转发]指的就是我上面提到的动态方法解析,重定向以及消息转发,我们先来看一张图: 动态方法解析: 从上图可以知道,当对一个实例对象obj发送一条消息func时[obj func],当前obj如果没有对func实现对应的方法,那么就runtime会调用+ (BOOL)resolveInstanceMethod:(SEL)sel方法允许开发者对当前受到的消息func做出响应,这就是动态方法解析。 继续拿上面的Person举例子,给Person类加一个体重weight属性
然后在.m文件中加入一下代码
然后可以在代码就调用Person的setWeight方法
这时候如果不重写+ (BOOL)resolveInstanceMethod:(SEL)sel方法本应该异常的,但是你可以发现程序会打印出信息:
重定向: 那么还是看图说话,如果没有重写+ (BOOL)resolveInstanceMethod:(SEL)sel方法,那就就会调用- (id)forwardingTargetForSelector:(SEL)aSelector方法,把这个消息让另一个对象来处理,这次叫做重定向。 跟着上面的例子走,先另一个类People用来等待重定向:
给新写的People类加一个weight方法,但是注意:People没有weight属性!
接下来我们重写- (id)forwardingTargetForSelector:(SEL)aSelector方法:
然后我们在刚才的执行代码中:
然后运行,经历过上面的例子你肯定知道不会异常啦,而且你会发现虽然你给weight属性赋值明明是75,可是打印结果是:weight = 70。这就是Person类- (id)forwardingTargetForSelector:(SEL)aSelector方法中把这条信息抛给了people对象,调用了People类的weight方法! 消息转发: 那么如果上面的两个方法都没有重写,并且消息依然是当前对象没有实现的方法,runtime才会启用消息转发调用– (void)forwardInvocation:(NSInvocation *)anInvocation,需要注意的是很多文章没有提到这个方法花费代价较大,如果要实现把消息转发类似的功能建议最好使用重定向,而且再调用这个方法前runtime会先调用- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector方法。 我们跟着上面的例子,继续给Person类加入属性:
以及上面提到的两个方法:
别忘记了在People类中添加对应的方法:
最后,我门只需要在执行代码块中加入代码:
结果显而易见,相信各位都知道将会打印信息:
写在最后 其实runtime就是我们无时无刻不在用的东西,只是人们习惯对看不到的东西怀有恐惧心理而已。我们平时的obj-C代码都是被runtime转译为c和汇编语言运行的。我个人认为大公司为什么喜欢在面试时问runtime相关的东西是因为大公司往往不仅仅要会干活的人,它还会要求这些会干活的人知道其中的原理!我们自己也应该要求自己或多或少的理解这些原理,知道我们为什么写出的obj-C代码经历了哪些过程run到我们的设备上,不要敲了很多年的代码还是一只只会干活的码农。 微信号:CocoaChinabbs |
|
来自: xiaotianyueye > 《iOS学习文章》