| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> 问题汇总-Runtime -> 正文阅读 |
|
[移动开发]问题汇总-Runtime |
Runtime
一 结构模型1 runtime的内存模型(isa、对象、类、metaclass、结构体的存储信息等)信息来源:阿里云开发者社区 1.1 对象OC中的对象指向的是一个objc_object指针类型,typedef struct objc_object *id; 1.2 类类:在OC中的类是用Class来表示的,实际上它指向的是一个objc_class的指针类型,typedef struct objc_class *Class;对应的结构体如下: 从结构体中定义的变量可知,OC的Class类型包括如下数据(即:元数据metadata):super_class(父类类对象);name(类对象的名称);version、info(版本和相关信息);instance_size(实例内存大小);ivars(实例变量列表);methodLists(方法列表);cache(缓存);protocols(实现的协议列表); 当然也包括一个isa指针,这说明Class也是一个对象类型,所以我们称之为类对象,这里的isa指向的是元类对象(metaclass),元类中保存了创建类对象(Class)的类方法的全部信息。
从图中可知,最终的基类(NSObject)的元类对象isa指向的是自己本身,从而形成一个闭环。
objc_method_list:存储了类的方法列表,可以通过class_copyMethodList获取。
objc_protocol_list:储存了类的协议列表,可以通过class_copyProtocolList获取。
2 为什么要设计metaclass信息来源:简书-robin2005 2.1 metaclass中的消息转发机制只用chcheLookup找方法缓存,命中则直接调用,未命中,则Object_msgSend_uncached 2.2 元类的存在走到这里一套方法发送的流程就都走完了,那这跟元类的存在有啥关系?我们都知道类方法是存储在元类中的,那么可不可以把元类干掉,在类中把实例方法和类方法 存在两个不同的副本中? 答:行是肯定可行的,但是在lookUpImpOrForward执行的时候就得标注上预期的cls到底是实例对象还是类对象,这也就意味着在查找方法的缓存时同样也需要判断cls到底是个啥。 倘若该该类存在同名的类方法和实例方法是该调用该方法呢?这也就意味着还得给给的该方法带上是类方法还是实例方法的标识,SEL并没有带上当前方法的类型(实例方法还是类方法),参数又多加一个,而我们现在的objc_msgSend()只接收了(id self,SEL _cmd,…)这类型参数,第一个自我就是消息的接收者,第二个就是方法,后续的…就是各式各样的参数。 通过元类就可以准确的解决上述问题,让各类各司其职,实例对象就干存储属性值的事,类对象存储实例方法列表,元类对象存储类方法列表,完美的符合6大设计原则中的单一职责,而且忽略了对对象类型的判断和方法类型的判断可以大大的提升消息发送的效率,并且在不同种类的方法走的都是相同套流程,在之后的维护上也很大节约了成本。 总结 本文从OC的消息机制分析了元类存在的意义,元类的存在简化的简化了实例方法和类方法的调用流程,大大提高了消息发送的效率 3 class_copyIvarList & class_copyPropertyList区别先看源码 3.1 class_copyPropertyListclass_copyPropertyList返回的仅仅是对象类的属性。 由源码可以看到:
返回的是一个objc_property_t,而objc_property_t是什么呢?
3.2 class_copyIvarListclass_copyIvarList遍历了内部所有的信息,成员变量和属性都能访问到
3.3 区别和联系class_copyPropertyList:返回的仅仅是对象类的属性。 还有一些在_uDoctor的博客中看到,学习一下~ Q1:通过关联对象方法添加的属性既不在PropertyList中也不再IvarList中,那在哪呢? Q2:两者为什么都不能访问到父类的成员变量? 4 class_rw_t 和 class_ro_t 的区别class_ro_t:一维数组,存储的是类在编译时就确定的一些信息,不可修改的原始核心。 5 category如何被加载的,两个category的load方法的加载顺序,两个category的同名方法的加载顺序,+load 方法调用顺序?5.1 类的load方法中,能调用分类的方法吗?是可以的。 5.2 Category的加载简书-forping 6 category & extension区别,能给NSObject添加Extension吗?7 消息转发机制,消息转发机制和其他语言的消息机制优劣对比7.1 消息转发机制是啥?消息发送机制:使用了运行时,通过selector快速去查找IMP的一个过程 对于C语言,函数的调用在编译的时候会决定调用哪个函数。编译完成之后直接顺序执行,无任何二义性。 7.2 消息转发机制的流程是啥?消息转发机制:当接收者收到消息后,无法处理该消息时(即:找不到调用的方法SEL),就会启动消息转发机制,流程如下: 第一阶段:咨询接收者,询问它是否可以动态增加这个方法实现 第二阶段:在第一阶段中,接收者无法动态增加这个方法实现,那么系统将询问是否有其他对象可能执行该方法,如果可以,系统将转发给这个对象处理。 第三阶段:在第二阶段中,如果没有其他对象可以处理,那么系统将该消息相关的细节封装成NSInvocation对象,再给接收者最后一次机会,如果这里仍然无法处理,接收者将收到doesNotRecognizeSelector方法调用,此时程序将crash。
7.3 在方法调用的时候,方法查询-> 动态解析-> 消息转发 之前做了什么1、编译器将代码 ??这样如果本类中没有的方法,就会去class中尝试查找,如果有,则返回class对象,让其执行,这样就实现了快速消息转发。 7.4 消息转发机制的优劣8 load、initialize方法的区别什么?在继承关系中他们有什么区别9 IMP、SEL、Method的区别和使用场景一个类(Class)持有一个分发表,在运行期分发消息,表中的每一个实体代表一个方法(Method),它的名字叫做选择子(SEL),对应着一种方法实现(IMP)。 9.1 IMP
代表函数指针,即函数执行的入口。该函数使用标准的 C调用。 9.2 SEL方法的名称,选择子代表方法在 Runtime期间的标识符。为 SEL类型,虽然 SEL是 objc_selector 结构体指针,但实际上它只是一个 C 字符串。在类加载的时候,编译器会生成与方法相对应的选择子,并注册到 Objective-C的 Runtime 运行系统。不论两个类是否存在依存关系,只要他们拥有相同的方法名,那么他们的SEL都是相同的。比如,有n个viewcontroller页面,每个页面都有一个viewdidload,每个页面的载入,肯定都是不尽相同的。但是我们可以通过打印,观察发现,这些viewdidload的SEL都是同一个。
因此类方法定义时,尽量不要用相同的名字,就算是变量类型不同也不行。否则会引起重复,例如:
9.3 Method
Method对开发者来说是一种不透明的类型,被隐藏在我们平时书写的类或对象的方法背后。它是一个objc_method结构体指针,我们可以看到该结构体中包含一个SEL和IMP,实际上相当于在SEL和IMP之间作了一个映射。有了SEL,我们便可以找到对应的IMP,从而调用方法的实现代码。 objc_method的定义为:
方法名 method_name 类型为 SEL,前面提到过相同名字的方法即使在不同类中定义,它们的方法选择器也相同。 |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 20:57:54- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |