首页 / IOS / iOS开发之runtime运行时机制
iOS开发之runtime运行时机制
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了iOS开发之runtime运行时机制,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3257字,纯文字阅读大概需要5分钟。
内容图文
![iOS开发之runtime运行时机制](/upload/InfoBanner/zyjiaocheng/1108/71f61a1121514ac99a387bd705cf6c79.jpg)
最近参加三次面试都有被问到runtime,也不知道面试官们自己懂不懂,反正就喜欢问,似乎就想把我唬住,来显示自己的对OC底层知识的理解很牛逼似的。(我现在开始看面试题,发现他们都喜欢问面试题的问题,我算明白了,都是应试教育惹的祸,大概他们以前没什么实际的app经验,所以准备了很多面试题,而我真的是能写app,先干活再找方法的人,面试不多,没什么面试经验,看来要开始碰壁多次才能掌握中国式面试)。因为不太懂runtime我就只能支支吾吾的说点零碎。我真的好几次努力想看一看runtime的知识,因为知道理解它对理解OC代码内部变化有一定帮助,不过真心觉得对开发没啥意义和用处,又是纯C的代码,现在开源项目那么多,基本都能参考别人的代码达到自己的目的,不知道这些面试官是不是经常用runtime来动态改变程序中的代码,他们开发的app就那么牛逼吗。不过为了面试,今天硬着头皮稍微学了点,不过还是没研究的让自己满意,还是不太明白如何动态的改变程序内部的方法或者变量。勉强写写今天的一点收获总结吧,依然很零碎就是,看官请自便。我发现这篇文章不错,看了几篇关于runtime的文章,这篇我感觉稍微通熟易懂一点,地址:《 Objective-C特性:Runtime 》,如果想了解更多请参考这篇吧。
什么是runtime(运行时机制)
Objective-C是基于C语言加入了面向对象特性和消息转发机制的动态语言,这意味着它不仅需要一个编译器,还需要Runtime系统来动态创建类和对象,进行消息发送和转发。
1.runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API。
2.平时编写的OC代码, 在程序运行过程中, 其实最终都是转成了runtime的C语言代码, runtime算是OC的幕后工作者
runtime的作用
runtime是属于OC的底层, 可以进行一些非常底层的操作(用OC是无法现实的, 不好实现)。
1.在程序运行过程中, 动态创建一个类(比如KVO的底层实现)
2.在程序运行过程中, 动态地为某个类添加属性\方法, 修改属性值\方法
3.遍历一个类的所有成员变量(属性)\所有方法
runtime相关应用
* NSCoding(归档和解档, 利用runtime遍历模型对象的所有属性)
* 字典 --> 模型 (利用runtime遍历模型对象的所有属性, 根据属性名从字典中取出对应的值, 设置到模型的属性上)
* KVO(利用runtime动态产生一个类)
* 用于封装框架(想怎么改就怎么改)
Runtime数据结构
在Objective-C中,使用[receiver message]语法并不会马上执行receiver对象的message方法的代码,而是向receiver发送一条message消息,这条消息可能由receiver来处理,也可能由转发给其他对象来处理,也有可能假装没有接收到这条消息而没有处理。其实[receiver message]被编译器转化为:
id objc_msgSend ( id self, SEL op, ... );
下面简单介绍runtime中重要的数据结构:
SEL |
表示方法选择器。其实它就是映射到方法的 C 字符串,你可以通过 Objc 编译器命令 @selector() 或者 Runtime 系统的 sel_registerName 函数来获取一个 SEL 类型的方法选择器。 |
id |
id 是通用类型指针,能够表示任何对象。 id 其实就是一个指向 objc_object 结构体指针,它包含一个 Class isa 成员,根据 isa 指针就可以顺藤摸瓜找到对象所属的类。 |
Class |
Class 表示对象所属的类。可以查看到 Class 其实就是一个 objc_class 结构体指针。在面向对象设计中,一切都是对象, Class 在设计中本身也是一个对象。 |
Method |
Method 表示类中的某个方法。其实 Method 就是一个指向 objc_method 结构体指针,它存储了方法名 (method_name) 、方法类型 (method_types) 和方法实现 (method_imp) 等信息。 |
Ivar |
Ivar 表示类中的实例变量。 Ivar 其实就是一个指向 objc_ivar 结构体指针,它包含了变量名 (ivar_name) 、变量类型 (ivar_type) 等信息。 |
IMP |
IMP 本质上就是一个函数指针,指向方法的实现。当你向某个对象发送一条信息,可以由这个函数指针来指定方法的实现,它最终就会执行那段代码,这样可以绕开消息传递阶段而去执行另一个方法实现。 |
Cache |
Cache 主要用来缓存。 Cache 其实就是一个存储 Method 的链表,主要是为了优化方法调用的性能。当调用方法时,优先在 Cache 查找,如果没有找到,再到 methodLists 查找。 |
Runtime消息发送
前面从objc_msgSend作为入口,逐步深入分析Runtime的数据结构,了解每个数据结构的作用和它们之间关系后,我们正式转入消息发送这个正题。
objc_msgSend函数
在前面已经提过,当某个对象使用语法[receiver message]来调用某个方法时,其实[receiver message]被编译器转化为:
id objc_msgSend ( id self, SEL op, ... );
现在让我们看一下objc_msgSend它具体是如何发送消息:
1.首先根据receiver对象的isa指针获取它对应的class
2.优先在class的cache查找message方法,如果找不到,再到methodLists查找
3.如果没有在class找到,再到super_class查找
4.一旦找到message这个方法,就执行它实现的IMP。
方法解析与消息转发
[receiver message]调用方法时,如果在message方法在receiver对象的类继承体系中没有找到方法,那怎么办?一般情况下,程序在运行时就会Crash掉,抛出 unrecognized selector sent to …类似这样的异常信息。但在抛出异常之前,还有三次机会按以下顺序让你拯救程序。
1.Method Resolution
2.Fast Forwarding
3.Normal Forwarding
三种方法的选择
Runtime提供三种方式来将原来的方法实现代替掉,那该怎样选择它们呢?
1.Method Resolution:由于Method Resolution不能像消息转发那样可以交给其他对象来处理,所以只适用于在原来的类中代替掉。
2.Fast Forwarding:它可以将消息处理转发给其他对象,使用范围更广,不只是限于原来的对象。
3.Normal Forwarding:它跟Fast Forwarding一样可以消息转发,但它能通过NSInvocation对象获取更多消息发送的信息,例如:target、selector、arguments和返回值等信息。
Method Swizzling
Method Swizzling就是在运行时将一个方法的实现代替为另一个方法的实现。如果能够利用好这个技巧,可以写出简洁、有效且维护性更好的代码。
总结
虽然在平时项目不是经常用到Objective-C的Runtime特性,但当你阅读一些iOS开源项目时,你就会发现很多时候都会用到。所以深入理解Objective-C的Runtime数据结构、消息转发机制有助于你更容易地阅读和学习开源项目。
原文:http://www.cnblogs.com/JackieHoo/p/5052848.html
内容总结
以上是互联网集市为您收集整理的iOS开发之runtime运行时机制全部内容,希望文章能够帮你解决iOS开发之runtime运行时机制所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。