RunTime

Runtime

一、数据结构

基础数据结构
1、objc_object

id = objc_object : isa_t为共用体

objc_objcet
2、objc_class

Class = objc_class: Class也是对象,称之为类对象,因为它继承自onjc_object

objc_class
3、isa_t

有两种类型,指针型isa、非指针型isa

isa_t
isa指向
4、cach_t
cach_t
cache_t
5、class_data_bits_t
class_data_bits_t
6、class_rw_t

例如分类1中添加的方法会在methods二维数组中的某个数组中存储

class_rw_t
7、class_ro_t

name:类名,可以通过NSClassFromString(name)获取该类

ivars:成员变量

properties:属性

class_ro_t
8、method_t

Const char* types: 函数的返回和参数的组合

method_t
9、Type Encodings

第一个参数@代表一个对象,第一个参数和第二个参数是固定的,@代表的是谁调用的,也就是self,第二个:表达的是方法选择器

Type Encodings

10、对象、类对象、元类对象

对象、类对象、元类对象

Root class指的就是NSObject

如果一个实例方法在元类对象以及根元类对象中都没有,会查找根类对象中的同名实例方法,并调用。

指向

问题

[self class];

[super class];

[self class]
[super class]

二、消息传递

消息传递
1、缓存查找

哈希查找

哈希查找
2、在类对象中查找
类查找
3、父类逐级查找
父类逐级查找
4、消息转发
消息转发

a、动态解析

我们可以根据方法类型(实例方法or类方法)重写一下方法,为类动态添加方法

+(BOOL)resolveInstanceMethod:(SEL)sel

+(BOOL)resolveClassMethod:(SEL)sel

在方法中调用一下方法来动态添加方法的实现

** 参数1:给哪个类添加

** 参数2:给哪个方法添加

** 参数3:方法的实现地址

** 参数4:方法的编码类型

BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)

动态解析
动态解析

b、消息转发

消息转发分为两步进行: Fast forwarding和 Normal forwarding

1> Fast forwarding : 将消息转发给一个其他的OC对象(找一个备用接收者)

重写以下方法,返回一个其他对象即可

+/- (id)forwardingTargetForSelector:(SEL)aSelector

Fast forwarding

2> Normal forwarding : 实现一个完整的消息转发过程

如果Fast forwarding没有解决可以重写以下两个方法启动完整的消息的转发

+/- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector

Runtime 会根据这个方法签名,创建一个NSInvocation对象(NSInvocation封装了未知消息的全部内容,

包括:方法调用者 target、方法名 selector、方法参数 argument 等),

然后调用第二个方法并将该NSInvocation对象作为参数传入。

+/- (void)forwardInvocation:(NSInvocation *)invocation

在该方法中:将未知消息转发给其它对象;改变未知消息的内容(如方法名、方法参数)再转发给其它对象;甚至可以定义任何逻辑。

Normal forwarding

⚠️如果第一个方法中没有返回方法签名,或者我们没有重写第二个方法,系统就会认为我们彻底不想处理这个消息了,

这时候就会调用以下方法

+/- (void)doesNotRecognizeSelector:(SEL)sel

方法并抛出经典的 crash:unrecognized selector sent to instance/class,结束 objc_msgSend 的全部流程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值