博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OC运行时和方法机制笔记
阅读量:6595 次
发布时间:2019-06-24

本文共 1583 字,大约阅读时间需要 5 分钟。

在OC当中,属性是对字段的一种特殊封装手段。

在编译期,编译器会将对字段的访问替换为内存偏移量,实质是一种硬编码。

如果增加一个字段,那么对象的内存排布就会改变,需要重新编译才行。

OC的做法是,把实例变量当做一种存储偏移量所用的特殊变量交给类对象来管理,偏移量会在运行期动态查找,这样无论何时访问实例变量,总能找到正确的地址。

可以在对象的内部(.m当中)直接使用下划线变量而不用getter或setter,会绕过方法派发过程,绕过内存管理和线程安全管理语义,会提升性能,同样不会触发KVO,会避免调用子类复写的setter方法。

 

在OC当中,所有对方法都会编译成C函数,当对象收到消息的时候,所有对函数的调用都由运行期动态绑定,甚至可以改写。

发送消息的代码是objc_msgSend(id, SEL, …)

收到消息的对象会去其方法表里找SEL,如果找不到就沿着继承体系向上找,如果最终还是找不到,则执行消息转发。

每个类当中都有一个快速映射表(缓存区),执行过的方法会缓存到这里,减少搜索时间。

当运行时找到对应的方法实现时,就会跳转过去,执行对应的C函数:

函数名大概是这个形式的:<返回值> Class_selector(id, SEL, …)

每个类里都有这样一张表格(方发表),key就是SEL,value就是IMP指针。objc_msgSend就是通过这个表找方法的。

 

上面是消息派发过程,OC还有消息转发过程。

当一个对象接收到无法执行的消息时,会调用

+(BOOL)resolveInstanceMethod:(SEL)selector

可以在这个方法里通过运行时动态创建一个方法来接受这个消息。

如果没有实现,则去找resolveClassMethod:方法。

CoreData当中@dynamic属性的get/set方法就是用这种手段生成的。

生成的过程当中,需要为这个selector指定一个IMP指针,这个指针指向一个C函数,比如CoreData操纵数据库的sqlite函数。

建议在这一步,就完成消息转发,因为这样会将选择子加入缓存。

 

如果这个阶段并没有为类添加方法,则运行时会询问能不能把这条消息交给其他备选接受者来处理。对应的方法:

-(id)forwardingTargetForSelector:(SEL)selector

如果没有方法来处理,则需要返回nil。

显然我们可以通过这个机制给一个对象内部组合另一个对象来处理某些方法,这样就模拟了多继承。

 

如果到了这一步依旧没有处理消息,则会触发

-(void)forwardInvocation:(NSInvocation *)invocation

NSInvocation当中封装了SEL、target和参数,这是最后一次改变消息路线的机会了。

如果还没有处理消息,则会抛异常。

 

在运行时检查对象的类型的过程叫做内省。

 

OC对象其实是id类型,

objc_object 是一个结构体,一个这种结构体类型的指针就是一个id。

这个结构体内部,含有一个Class类型的变量isa。

类似的,还有一个结构体类型叫objc_class,指向它的指针就是Class。

这个结构体里面存放一个类的元数据:

首先,它内部存储了一个Class isa变量,它指向类的元类。

这个类里面有:

元类指针,父类指针,名字,版本,info,实例size,指向变量表的指针,指向方法表的指针的指针,指向缓存表的指针,指向协议表的指针。

两个元类之间也有继承关系。根类的元类的元类就是自身。

isMemberOfClass:和isKindOfClass就是通过objc_class当中的指针来确定结果的。

 

转载于:https://www.cnblogs.com/Steak/p/4033019.html

你可能感兴趣的文章
指静脉识别:一个“销声匿迹”了近二十年的多模态生物识别技术要“重出江湖”...
查看>>
小议阿里云"数加"平台对企业有何帮助?
查看>>
《C语言程序设计进阶教程》一2.3.2 函数实参
查看>>
智能硬件的未来发展:自主研发和AI将成为关键
查看>>
超图发布SuperMap GIS 8C(2017) 进一步挖掘空间大数据价值
查看>>
“聚光灯”下的数梦工场 首提“新型互联网”战略
查看>>
IBM预通过R语言扩展 简化Watson系统的应用
查看>>
施耐德电气推出EcoStruxure架构与平台,开启转型之路
查看>>
NVIDIA与阿里云达成战略合作 共同拓展深度学习市场
查看>>
数据中心机房对环境的新要求
查看>>
一个页面标题和过滤输出的解决方案(下)
查看>>
JSP连接access数据库
查看>>
Loadrunner监控服务器资源
查看>>
Pandas:按条件进行行选择
查看>>
spring boot 自定义规则访问获取内部或者外部静态资源图片
查看>>
Object类
查看>>
前后端上传到同一个Git仓库
查看>>
【云计算的1024种玩法】使用 NAS 文件储存低价获得好磁盘性能
查看>>
Coding打坐
查看>>
springmvc + mybatis + ehcache + redis架构
查看>>