iOS 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 的全部流程。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • runtime 和 runloop 作为一个程序员进阶是必须的,也是非常重要的, 在面试过程中是经常会被问到的, ...
    SOI阅读 21,848评论 3 63
  • Objective-C是基于C语言加入了面向对象特性和消息转发机制的动态语言,这意味着它不仅需要一个编译器,还需要...
    iOSCode阅读 145评论 0 0
  • OC方法调用的本质:消息发送机制 - msg_Send. OC方法调用的本质就是给对象发送消息:objc_msgS...
    蒋斌文阅读 255评论 0 3
  • runtime 和 runloop 作为一个程序员进阶是必须的,也是非常重要的, 在面试过程中是经常会被问到的, ...
    made_China阅读 1,226评论 0 7
  • 一、数据结构:objc_object, objc_class, isa, class_data_bits_t, c...
    曼谷第一开膛手阅读 261评论 0 0